diff --git a/.gitignore b/.gitignore index 7d49943..508a755 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ test-ledger .yarn Makefile +expand.rs +# For devenv tests, copy from ../light-protocol/cli/accounts +# cp ../light-protocol/cli/accounts target/deploy +# cp ../light-protocol/target/deploy/*.so target/deploy +cli/ diff --git a/Anchor.toml b/Anchor.toml index f06fe87..bd33d8c 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -25,6 +25,7 @@ test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.test.ts" [test] startup_wait = 10000 +upgradeable = true [test.validator] url = "https://api.mainnet-beta.solana.com" @@ -34,3 +35,9 @@ address = "DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8" # pool fee receiver [[test.validator.clone]] address = "D4FPEruKEHrG5TenZ2mpDGEfu1iUvTiqBxvpU8HLBvC2" # index 0 AMM Config account + + +[idl] +typescript = true +idl_dir = "target/idl" +types_dir = "target/types" diff --git a/Cargo.lock b/Cargo.lock index 9116c0e..785203f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,39 +12,6 @@ dependencies = [ "regex", ] -[[package]] -name = "account-compression" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "aligned-sized", - "anchor-lang", - "bytemuck", - "light-account-checks", - "light-batched-merkle-tree", - "light-bounded-vec", - "light-compressed-account", - "light-concurrent-merkle-tree", - "light-hash-set", - "light-hasher", - "light-indexed-merkle-tree", - "light-merkle-tree-metadata", - "light-zero-copy", - "num-bigint 0.4.6", - "solana-sdk", - "solana-security-txt", - "zerocopy", -] - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -87,6 +54,53 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-precompiles" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d60d73657792af7f2464e9181d13c3979e94bb09841d9ffa014eef4ef0492b77" +dependencies = [ + "agave-feature-set", + "bincode", + "digest 0.10.7", + "ed25519-dalek", + "libsecp256k1", + "openssl", + "sha3", + "solana-ed25519-program", + "solana-message", + "solana-precompile-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-secp256k1-program", + "solana-secp256r1-program", +] + +[[package]] +name = "agave-reserved-account-keys" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8289c8a8a2ef5aa10ce49a070f360f4e035ee3410b8d8f3580fb39d8cf042581" +dependencies = [ + "agave-feature-set", + "solana-pubkey", + "solana-sdk-ids", +] + [[package]] name = "ahash" version = "0.8.12" @@ -94,7 +108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -102,9 +116,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -112,11 +126,12 @@ dependencies = [ [[package]] name = "aligned-sized" version = "1.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48a526ec4434d531d488af59fe866f36b310fe8906691c75dffa664450a3800a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -216,25 +231,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "anchor-client" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3e91b12501d37c8f07de9da8c7d22067998a7760a515231187afb47ded225" -dependencies = [ - "anchor-lang", - "anyhow", - "futures", - "regex", - "serde", - "solana-account-decoder", - "solana-client", - "solana-sdk", - "thiserror 1.0.69", - "tokio", - "url", -] - [[package]] name = "anchor-derive-accounts" version = "0.31.1" @@ -319,23 +315,6 @@ dependencies = [ "serde", ] -[[package]] -name = "anchor-spl" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c08cb5d762c0694f74bd02c9a5b04ea53cefc496e2c27b3234acffca5cd076b" -dependencies = [ - "anchor-lang", - "mpl-token-metadata", - "spl-associated-token-account", - "spl-memo", - "spl-pod", - "spl-token", - "spl-token-2022 6.0.0", - "spl-token-group-interface", - "spl-token-metadata-interface", -] - [[package]] name = "anchor-syn" version = "0.31.1" @@ -355,12 +334,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[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" @@ -379,61 +352,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "anstream" -version = "0.6.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.59.0", -] - [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "ark-bn254" @@ -487,7 +410,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.4", + "hashbrown 0.15.2", "itertools 0.13.0", "num-bigint 0.4.6", "num-integer", @@ -552,7 +475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -578,7 +501,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -606,7 +529,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.4", + "hashbrown 0.15.2", ] [[package]] @@ -653,7 +576,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -695,112 +618,27 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" -[[package]] -name = "asn1-rs" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure 0.12.6", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-compression" -version = "0.4.27" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" +checksum = "d10e4f991a553474232bc0a31799f6d24b034a84c0971d80d2e2f78b2e576e40" dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", + "compression-codecs", + "compression-core", "pin-project-lite", "tokio", ] -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener 5.4.0", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -815,7 +653,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] @@ -826,21 +664,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.12.3" @@ -865,18 +688,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bb8" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89aabfae550a5c44b43ab941844ffcd2e993cb6900b342debf59e9ea74acdb8" -dependencies = [ - "async-trait", - "futures-util", - "parking_lot", - "tokio", -] - [[package]] name = "bincode" version = "1.3.3" @@ -909,11 +720,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -972,11 +783,11 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ - "borsh-derive 1.5.7", + "borsh-derive 1.6.0", "cfg_aliases", ] @@ -995,15 +806,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -1030,9 +841,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.1" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1060,9 +871,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bv" @@ -1074,24 +885,30 @@ dependencies = [ "serde", ] +[[package]] +name = "bytecount" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "441473f2b4b0459a68628c744bc61d23e730fb00128b841d30fa4bb3972257e4" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -1102,19 +919,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "caps" -version = "0.5.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" -dependencies = [ - "libc", - "thiserror 1.0.69", -] +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cargo_toml" @@ -1128,26 +935,21 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.30" +version = "1.2.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -1163,16 +965,15 @@ checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -1192,141 +993,54 @@ dependencies = [ ] [[package]] -name = "clap" -version = "4.5.41" +name = "combine" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" dependencies = [ - "clap_builder", - "clap_derive", + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", ] [[package]] -name = "clap_builder" -version = "4.5.41" +name = "compression-codecs" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", + "brotli", + "compression-core", + "flate2", + "memchr", ] [[package]] -name = "clap_derive" -version = "4.5.41" +name = "compression-core" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.104", -] +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] -name = "clap_lex" -version = "0.7.5" +name = "console" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] [[package]] -name = "client" -version = "0.1.0" -dependencies = [ - "anchor-client", - "anchor-lang", - "anchor-spl", - "anyhow", - "arrayref", - "base64 0.21.7", - "bincode", - "bs58", - "bytemuck", - "clap", - "colorful", - "configparser", - "hex", - "rand 0.9.2", - "raydium-cp-swap", - "regex", - "serde", - "serde_json", - "solana-account-decoder", - "solana-client", - "solana-sdk", - "solana-transaction-status", -] - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "colorful" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb474a9c3219a8254ead020421ecf1b90427f29b55f6aae9a2471fa62c126ef" - -[[package]] -name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" -dependencies = [ - "ascii", - "byteorder", - "either", - "memchr", - "unreachable", -] - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "configparser" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" - -[[package]] -name = "console" -version = "0.15.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" -dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width", - "windows-sys 0.59.0", -] - -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +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", @@ -1358,16 +1072,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1392,20 +1096,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "create-address-test-program" -version = "1.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "account-compression", - "anchor-lang", - "light-compressed-account", - "light-hasher", - "light-sdk", - "light-sdk-types", - "light-system-program-anchor", -] - [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -1448,9 +1138,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1515,14 +1205,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -1530,84 +1220,37 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.104", -] - -[[package]] -name = "dashmap" -version = "5.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" -dependencies = [ - "cfg-if", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "der-parser" -version = "8.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint 0.4.6", - "num-traits", - "rusticata-macros", + "syn 2.0.114", ] [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -1655,30 +1298,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", -] - -[[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.104", + "syn 2.0.114", ] [[package]] @@ -1746,10 +1366,10 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" dependencies = [ - "enum-ordinalize 4.3.0", + "enum-ordinalize 4.3.2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -1784,13 +1404,13 @@ dependencies = [ [[package]] name = "enum-iterator-derive" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -1803,27 +1423,27 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "enum-ordinalize" -version = "4.3.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" dependencies = [ "enum-ordinalize-derive", ] [[package]] name = "enum-ordinalize-derive" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -1857,51 +1477,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener 5.4.0", - "pin-project-lite", -] - -[[package]] -name = "fastbloom" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27cea6e7f512d43b098939ff4d5a5d6fe3db07971e1d05176fe26c642d33f5b8" -dependencies = [ - "getrandom 0.3.3", - "rand 0.9.2", - "siphasher 1.0.1", - "wide", + "windows-sys 0.61.2", ] [[package]] @@ -1922,6 +1503,21 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "find-msvc-tools" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" + +[[package]] +name = "five8" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" +dependencies = [ + "five8_core", +] + [[package]] name = "five8_const" version = "0.1.4" @@ -1939,9 +1535,9 @@ checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ "crc32fast", "miniz_oxide", @@ -1953,6 +1549,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1968,49 +1570,11 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "forester-utils" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "account-compression", - "anchor-lang", - "async-stream", - "async-trait", - "bb8", - "futures", - "governor 0.8.1", - "light-account-checks", - "light-batched-merkle-tree", - "light-client", - "light-compressed-account", - "light-concurrent-merkle-tree", - "light-hash-set", - "light-hasher", - "light-indexed-array", - "light-indexed-merkle-tree", - "light-merkle-tree-metadata", - "light-prover-client", - "light-registry", - "light-sdk", - "light-sparse-merkle-tree", - "num-bigint 0.4.6", - "num-traits", - "rand 0.8.5", - "reqwest 0.12.22", - "serde", - "serde_json", - "solana-sdk", - "thiserror 2.0.12", - "tokio", - "tracing", -] - [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -2077,7 +1641,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -2092,12 +1656,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" - [[package]] name = "futures-util" version = "0.3.31" @@ -2151,9 +1709,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -2164,67 +1722,18 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "governor" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" -dependencies = [ - "cfg-if", - "dashmap 5.5.3", - "futures", - "futures-timer", - "no-std-compat", - "nonzero_ext", - "parking_lot", - "portable-atomic", - "quanta", - "rand 0.8.5", - "smallvec", - "spinning_top", -] - -[[package]] -name = "governor" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be93b4ec2e4710b04d9264c0c7350cdd62a8c20e5e4ac732552ebb8f0debe8eb" -dependencies = [ - "cfg-if", - "dashmap 6.1.0", - "futures-sink", - "futures-timer", - "futures-util", - "getrandom 0.3.3", - "no-std-compat", - "nonzero_ext", - "parking_lot", - "portable-atomic", - "quanta", - "rand 0.9.2", - "smallvec", - "spinning_top", - "web-time", -] - [[package]] name = "groth16-solana" version = "0.2.0" @@ -2252,37 +1761,37 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.10.0", + "indexmap 2.13.0", "slab", "tokio", - "tokio-util 0.7.15", + "tokio-util 0.7.18", "tracing", ] [[package]] name = "h2" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.3.1", - "indexmap 2.10.0", + "http 1.4.0", + "indexmap 2.13.0", "slab", "tokio", - "tokio-util 0.7.15", + "tokio-util 0.7.18", "tracing", ] [[package]] name = "hash32" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ "byteorder", ] @@ -2304,18 +1813,20 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" -dependencies = [ - "allocator-api2", -] +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -2326,12 +1837,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2347,24 +1852,12 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[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" @@ -2408,12 +1901,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -2435,7 +1927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -2446,7 +1938,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -2465,9 +1957,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" @@ -2495,19 +1987,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", - "h2 0.4.11", - "http 1.3.1", + "futures-core", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "httparse", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -2533,14 +2027,15 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.6.0", + "http 1.4.0", + "hyper 1.8.1", "hyper-util", - "rustls 0.23.29", + "rustls 0.23.36", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls 0.26.4", "tower-service", + "webpki-roots 1.0.5", ] [[package]] @@ -2564,7 +2059,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-util", "native-tls", "tokio", @@ -2574,23 +2069,23 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.8.1", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.6.1", "system-configuration 0.6.1", "tokio", "tower-service", @@ -2600,9 +2095,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2624,9 +2119,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -2637,9 +2132,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -2650,11 +2145,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -2665,42 +2159,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -2716,9 +2206,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -2748,13 +2238,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.16.1", "serde", + "serde_core", ] [[package]] @@ -2779,17 +2270,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "io-uring" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -2798,20 +2278,14 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", ] -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - [[package]] name = "itertools" version = "0.10.5" @@ -2850,47 +2324,25 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine 4.6.7", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -2911,6 +2363,16 @@ dependencies = [ "serde_json", ] +[[package]] +name = "kaigan" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ba15de5aeb137f0f65aa3bf82187647f1285abfe5b20c80c2c37f7007ad519a" +dependencies = [ + "borsh 0.10.4", + "serde", +] + [[package]] name = "keccak" version = "0.1.5" @@ -2928,9 +2390,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libsecp256k1" @@ -2982,57 +2444,86 @@ dependencies = [ [[package]] name = "light-account-checks" -version = "0.3.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0785da22cd4a7667583141ca56c790a5c8afa2b22ad2a08204d78881035524e8" dependencies = [ "solana-account-info", + "solana-msg", "solana-program-error", "solana-pubkey", "solana-sysvar", - "thiserror 2.0.12", + "thiserror 2.0.18", +] + +[[package]] +name = "light-anchor-spl" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c802e3de6de4bb03bc9e9bacbba8aa94823a083046aaf0ef275b1321984e3" +dependencies = [ + "anchor-lang", + "spl-associated-token-account 6.0.0", + "spl-memo", + "spl-pod", + "spl-token 7.0.0", + "spl-token-2022 6.0.0", + "spl-token-group-interface 0.5.0", + "spl-token-metadata-interface 0.6.0", +] + +[[package]] +name = "light-array-map" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859dc5b406a8bf0b114f686e6f2e36d0e939bad6f579492a520d309b52fde1f8" +dependencies = [ + "tinyvec", ] [[package]] name = "light-batched-merkle-tree" -version = "0.3.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13cb8bc778065ee71d1990fdc94112e35dc63a5e387a323284a49f40d123d8e0" dependencies = [ "aligned-sized", "borsh 0.10.4", "light-account-checks", "light-bloom-filter", - "light-compressed-account", + "light-compressed-account 0.8.0", "light-hasher", "light-macros", "light-merkle-tree-metadata", "light-verifier", - "light-zero-copy", + "light-zero-copy 0.6.0", "solana-account-info", "solana-msg", "solana-program-error", "solana-pubkey", "solana-sysvar", - "thiserror 2.0.12", + "thiserror 2.0.18", "zerocopy", ] [[package]] name = "light-bloom-filter" -version = "0.3.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a609e3c9179f0ae8488cc70c5413c86dfd97dad7ad85fee2ad8da2d0a11e61" dependencies = [ "bitvec", "num-bigint 0.4.6", "solana-nostd-keccak", "solana-program-error", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "light-bounded-vec" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233a69f003522990dadcf923b436094ffcb55326a2c3cef7f67acdbcb6e5b039" +checksum = "58cfa375d028164719e3ffef93d2e5c27855cc8a5bb5bf257b868d17c12a3e66" dependencies = [ "bytemuck", "memoffset", @@ -3042,26 +2533,33 @@ dependencies = [ [[package]] name = "light-client" -version = "0.13.1" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1f3cd013364dbe5c45a9e9a8faee1af30dccb600cd56a41e296ed8d5684768" dependencies = [ + "anchor-lang", "async-trait", "base64 0.13.1", "borsh 0.10.4", "bs58", - "bytemuck", + "futures", "lazy_static", - "light-compressed-account", + "light-compressed-account 0.8.0", + "light-compressible", "light-concurrent-merkle-tree", + "light-event", "light-hasher", "light-indexed-merkle-tree", "light-merkle-tree-metadata", "light-prover-client", "light-sdk", + "light-token", + "light-token-interface", + "litesvm", "num-bigint 0.4.6", - "num-traits", "photon-api", "rand 0.8.5", + "smallvec", "solana-account", "solana-account-decoder-client-types", "solana-address-lookup-table-interface", @@ -3069,10 +2567,10 @@ dependencies = [ "solana-clock", "solana-commitment-config", "solana-compute-budget-interface", - "solana-epoch-info", "solana-hash", "solana-instruction", "solana-keypair", + "solana-message", "solana-program-error", "solana-pubkey", "solana-rpc-client", @@ -3081,129 +2579,136 @@ dependencies = [ "solana-transaction", "solana-transaction-error", "solana-transaction-status-client-types", - "thiserror 2.0.12", + "spl-pod", + "spl-token-2022-interface", + "thiserror 2.0.18", "tokio", "tracing", ] [[package]] name = "light-compressed-account" -version = "0.3.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058df2733fa6a3e4bda6f162a6c5d41f10fc8c6f6ddb992af1de76b60214e4a6" dependencies = [ - "anchor-lang", "borsh 0.10.4", - "bytemuck", "light-hasher", "light-macros", - "light-zero-copy", - "solana-program-error", - "solana-pubkey", - "thiserror 2.0.12", + "light-program-profiler", + "light-zero-copy 0.5.0", + "thiserror 2.0.18", + "tinyvec", "zerocopy", ] [[package]] -name = "light-compressed-token" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +name = "light-compressed-account" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "768ae5a56d8c9cf315d132b3faa5b067f95b3d6a294c579e82f8f0e0bf29c7cc" dependencies = [ - "account-compression", "anchor-lang", - "anchor-spl", - "light-compressed-account", + "borsh 0.10.4", + "bytemuck", "light-hasher", - "light-heap", - "light-system-program-anchor", - "light-zero-copy", - "solana-sdk", - "solana-security-txt", - "spl-token", - "spl-token-2022 7.0.0", + "light-macros", + "light-poseidon 0.3.0", + "light-program-profiler", + "light-zero-copy 0.6.0", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "thiserror 2.0.18", + "tinyvec", "zerocopy", ] [[package]] -name = "light-compressible-client" -version = "0.13.1" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +name = "light-compressible" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff0f0065beb8d16df587b3ea17082e11dea3f67c98813b4bcc061eecd94561f" dependencies = [ + "aligned-sized", "anchor-lang", "borsh 0.10.4", - "light-client", - "light-sdk", - "solana-instruction", + "bytemuck", + "light-account-checks", + "light-compressed-account 0.8.0", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-sdk-types", + "light-zero-copy 0.6.0", + "pinocchio-pubkey", "solana-pubkey", - "thiserror 2.0.12", + "thiserror 2.0.18", + "zerocopy", ] [[package]] name = "light-concurrent-merkle-tree" -version = "2.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db96f47253a0907aaa46dac15cecb27b5510130e48da0b36690dcd2e99a6d558" dependencies = [ "borsh 0.10.4", "light-bounded-vec", "light-hasher", "memoffset", "solana-program-error", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] -name = "light-hash-set" -version = "2.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +name = "light-event" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1674c9d85b32a9e8abb90cccdee18e35ae29daa1126fdb81a8a28c0a54802096" dependencies = [ + "borsh 0.10.4", + "light-compressed-account 0.8.0", "light-hasher", - "num-bigint 0.4.6", - "num-traits", - "solana-program-error", - "thiserror 2.0.12", + "light-zero-copy 0.6.0", + "thiserror 2.0.18", ] [[package]] name = "light-hasher" -version = "3.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c822662e6e109bac0e132a43fd52a4ef684811245a794e048cf9cda001e934c8" dependencies = [ "ark-bn254 0.5.0", "ark-ff 0.5.0", - "arrayvec", "borsh 0.10.4", "light-poseidon 0.3.0", "num-bigint 0.4.6", "sha2 0.10.9", "sha3", - "solana-nostd-keccak", "solana-program-error", - "solana-pubkey", - "thiserror 2.0.12", -] - -[[package]] -name = "light-heap" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "anchor-lang", + "thiserror 2.0.18", + "tinyvec", ] [[package]] name = "light-indexed-array" -version = "0.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f14f984030d86b6f07bd8f5ae04e2c40fcd0c3bdfcc7a291fff1ed59c9e6554" dependencies = [ "light-hasher", "num-bigint 0.4.6", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "light-indexed-merkle-tree" -version = "2.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0824755289075f28de2820fc7d4ec4e6b9e99d404e033c07338b91cce8c71fb8" dependencies = [ "light-bounded-vec", "light-concurrent-merkle-tree", @@ -3212,46 +2717,50 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "solana-program-error", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "light-macros" -version = "2.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179ac51cadc1d0ca047b4d6265a7cc245ca3affc16a20a2749585aa6464d39c2" dependencies = [ "bs58", "proc-macro2", "quote", - "syn 2.0.104", + "solana-pubkey", + "syn 2.0.114", ] [[package]] name = "light-merkle-tree-metadata" -version = "0.3.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d08edcc194eef61b0f499934ce398122d54ac57505d44480e5f079a4220566" dependencies = [ "anchor-lang", "borsh 0.10.4", "bytemuck", - "light-compressed-account", + "light-compressed-account 0.8.0", "solana-msg", "solana-program-error", "solana-sysvar", - "thiserror 2.0.12", + "thiserror 2.0.18", "zerocopy", ] [[package]] name = "light-merkle-tree-reference" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d480f62ca32b38a6231bbc5310d693f91d6b5bdcc18bb13c2d9aab7a1c90e8" dependencies = [ "light-hasher", "light-indexed-array", "num-bigint 0.4.6", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -3278,37 +2787,63 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "light-profiler-macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a8be18fe4de58a6f754caa74a3fbc6d8a758a26f1f3c24d5b0f5b55df5f5408" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "light-program-profiler" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1d345871581aebd8825868a3f08410290aa1cdddcb189ca7f7e588f61d79fcf" +dependencies = [ + "light-profiler-macro", +] + [[package]] name = "light-program-test" -version = "0.13.2" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a981dfbc19c529543ab1dd8d100319b89aac053b81415a681d1474c986218307" dependencies = [ - "account-compression", "anchor-lang", "async-trait", + "base64 0.13.1", "borsh 0.10.4", + "bs58", "bytemuck", - "light-batched-merkle-tree", + "chrono", "light-client", - "light-compressed-account", - "light-compressed-token", - "light-compressible-client", - "light-concurrent-merkle-tree", + "light-compressed-account 0.8.0", + "light-compressible", + "light-event", "light-hasher", "light-indexed-array", "light-indexed-merkle-tree", "light-merkle-tree-metadata", "light-merkle-tree-reference", "light-prover-client", - "light-registry", "light-sdk", + "light-sdk-types", + "light-token", + "light-token-interface", + "light-zero-copy 0.6.0", "litesvm", "log", "num-bigint 0.4.6", "num-traits", "photon-api", "rand 0.8.5", - "reqwest 0.12.22", + "reqwest 0.12.28", + "serde", + "serde_json", "solana-account", "solana-banks-client", "solana-compute-budget", @@ -3317,18 +2852,23 @@ dependencies = [ "solana-rpc-client-api", "solana-sdk", "solana-transaction", + "solana-transaction-status", "solana-transaction-status-client-types", + "spl-token-2022 7.0.0", + "tabled", "tokio", ] [[package]] name = "light-prover-client" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75d8c9b8b6e9d445b9ef27467da592ee231e614282c3c0bd2f30f567eb904845" dependencies = [ "ark-bn254 0.5.0", "ark-serialize 0.5.0", "ark-std 0.5.0", + "light-compressed-account 0.7.0", "light-hasher", "light-indexed-array", "light-sparse-merkle-tree", @@ -3338,190 +2878,242 @@ dependencies = [ "serde", "serde_json", "solana-bn254", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", ] -[[package]] -name = "light-registry" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "account-compression", - "aligned-sized", - "anchor-lang", - "light-batched-merkle-tree", - "light-merkle-tree-metadata", - "light-system-program-anchor", - "solana-sdk", - "solana-security-txt", -] - [[package]] name = "light-sdk" -version = "0.13.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dece106ebd0897bd23a12bad040e0999d93b54447d0473739f91b1f83b1d331" dependencies = [ "anchor-lang", - "arrayvec", + "bincode", "borsh 0.10.4", "light-account-checks", - "light-compressed-account", + "light-compressed-account 0.8.0", + "light-compressible", "light-hasher", "light-macros", "light-sdk-macros", "light-sdk-types", - "light-zero-copy", + "light-zero-copy 0.6.0", "num-bigint 0.4.6", "solana-account-info", "solana-clock", "solana-cpi", "solana-instruction", + "solana-loader-v3-interface", "solana-msg", + "solana-program", "solana-program-error", "solana-pubkey", - "solana-rent", "solana-system-interface", "solana-sysvar", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "light-sdk-macros" -version = "0.13.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d91992fa08093b1a274b3baed1d8368de794cc2645f9942718e5fe47a27dc2" dependencies = [ - "heck 0.4.1", + "darling", "light-hasher", - "light-poseidon 0.3.0", + "light-sdk-types", "proc-macro2", "quote", "solana-pubkey", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "light-sdk-types" -version = "0.13.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b765f0a39428a137b8d449fa60ba147194cdbff08aa0add598c6047fff2cb7d2" dependencies = [ "anchor-lang", "borsh 0.10.4", "light-account-checks", - "light-compressed-account", + "light-compressed-account 0.8.0", "light-hasher", "light-macros", - "light-zero-copy", "solana-msg", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "light-sparse-merkle-tree" -version = "0.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4251e79b6c63f4946572dcfd7623680ad0f9e0efe1a761a944733333c5645063" dependencies = [ "light-hasher", "light-indexed-array", "num-bigint 0.4.6", "num-traits", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] -name = "light-system-program-anchor" -version = "2.0.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +name = "light-token" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62907a12a9801200e5f4c03bb7f2dbdd9aa679223a959167c456a06005291d79" dependencies = [ - "account-compression", - "aligned-sized", "anchor-lang", - "light-compressed-account", - "light-zero-copy", - "zerocopy", -] - -[[package]] -name = "light-test-utils" -version = "1.2.1" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" -dependencies = [ - "account-compression", - "anchor-lang", - "anchor-spl", - "create-address-test-program", - "forester-utils", + "arrayvec", + "borsh 0.10.4", "light-account-checks", "light-batched-merkle-tree", - "light-client", - "light-compressed-account", - "light-compressed-token", - "light-concurrent-merkle-tree", - "light-hasher", - "light-indexed-array", - "light-indexed-merkle-tree", - "light-merkle-tree-metadata", - "light-merkle-tree-reference", - "light-program-test", - "light-prover-client", - "light-registry", + "light-compressed-account 0.8.0", + "light-compressible", + "light-macros", + "light-program-profiler", "light-sdk", - "light-sparse-merkle-tree", - "light-system-program-anchor", - "log", - "num-bigint 0.4.6", - "num-traits", - "rand 0.8.5", - "reqwest 0.12.22", - "solana-banks-client", - "solana-sdk", - "spl-token", + "light-sdk-macros", + "light-sdk-types", + "light-token-interface", + "light-token-types", + "light-zero-copy 0.6.0", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-pod", + "thiserror 2.0.18", +] + +[[package]] +name = "light-token-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb19b8e268a0154a8e13b3a8f6f43fa4928643e2de102d98a90b2af21f482ba" +dependencies = [ + "aligned-sized", + "anchor-lang", + "borsh 0.10.4", + "bytemuck", + "light-array-map", + "light-compressed-account 0.8.0", + "light-compressible", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-zero-copy 0.6.0", + "pinocchio", + "pinocchio-pubkey", + "solana-account-info", + "solana-pubkey", + "spl-pod", "spl-token-2022 7.0.0", - "thiserror 2.0.12", + "thiserror 2.0.18", + "tinyvec", + "zerocopy", +] + +[[package]] +name = "light-token-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278dddbf18d104f1225c480ca6d7b8710e1f9ff4104f24be70c522ecb6ed1dfc" +dependencies = [ + "anchor-lang", + "borsh 0.10.4", + "light-account-checks", + "light-compressed-account 0.8.0", + "light-macros", + "light-sdk-types", + "solana-msg", + "thiserror 2.0.18", ] [[package]] name = "light-verifier" -version = "2.1.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f35f47736be493b60d8b56ef0c8e94afd6a99efafebb257f62b0b545e9aacab" dependencies = [ "groth16-solana", - "light-compressed-account", - "thiserror 2.0.12", + "light-compressed-account 0.8.0", + "thiserror 2.0.18", ] [[package]] name = "light-zero-copy" -version = "0.2.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8862f463792fd60ae8f5dc418150c16213e302e19d54fba0694cf8515be5ff" +dependencies = [ + "light-zero-copy-derive 0.5.0", + "zerocopy", +] + +[[package]] +name = "light-zero-copy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5621fb515e14af46148699c0b65334aabe230a1d2cbd06736ccc7a408c8a4af" dependencies = [ + "light-zero-copy-derive 0.6.0", "solana-program-error", - "thiserror 2.0.12", "zerocopy", ] +[[package]] +name = "light-zero-copy-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af086d52100b3cab1f2993b146adc7a69fa6aaa878ae4c19514c77c50304379" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "light-zero-copy-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c46425e5c7ab5203ff5c86ae2615b169cca55f9283f5f60f5dd74143be6934" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "litesvm" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7e5f4462f34439adcfcab58099bc7a89c67a17f8240b84a993b8b705c1becb" +checksum = "23bca37ac374948b348e29c74b324dc36f18bbbd1ccf80e2046d967521cbd143" dependencies = [ + "agave-feature-set", + "agave-precompiles", + "agave-reserved-account-keys", "ansi_term", "bincode", - "indexmap 2.10.0", + "indexmap 2.13.0", "itertools 0.14.0", "log", "solana-account", @@ -3531,10 +3123,8 @@ dependencies = [ "solana-clock", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-config-program", "solana-epoch-rewards", "solana-epoch-schedule", - "solana-feature-set", "solana-fee", "solana-fee-structure", "solana-hash", @@ -3545,17 +3135,15 @@ dependencies = [ "solana-loader-v3-interface", "solana-loader-v4-interface", "solana-log-collector", - "solana-measure", "solana-message", - "solana-native-token", + "solana-native-token 3.0.0", "solana-nonce", "solana-nonce-account", - "solana-precompiles", + "solana-precompile-error", "solana-program-error", "solana-program-runtime", "solana-pubkey", "solana-rent", - "solana-reserved-account-keys", "solana-sdk-ids", "solana-sha256-hasher", "solana-signature", @@ -3563,6 +3151,7 @@ dependencies = [ "solana-slot-hashes", "solana-slot-history", "solana-stake-interface", + "solana-svm-callback", "solana-svm-transaction", "solana-system-interface", "solana-system-program", @@ -3573,24 +3162,23 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-vote-program", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru-slab" @@ -3600,9 +3188,9 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -3650,12 +3238,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -3663,30 +3245,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "mpl-token-metadata" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6a3000e761d3b2d685662a3a9ee99826f9369fb033bd1bc7011b1cf02ed9" -dependencies = [ - "borsh 0.10.4", - "num-derive 0.3.3", - "num-traits", - "solana-program", - "thiserror 1.0.69", + "windows-sys 0.61.2", ] [[package]] @@ -3701,46 +3271,11 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework 2.11.1", + "security-framework", "security-framework-sys", "tempfile", ] -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "cfg_aliases", - "libc", - "memoffset", -] - -[[package]] -name = "no-std-compat" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nonzero_ext" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" - [[package]] name = "num" version = "0.2.1" @@ -3774,7 +3309,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "rand 0.8.5", "serde", ] @@ -3794,17 +3328,6 @@ 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" @@ -3813,7 +3336,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -3857,21 +3380,11 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi 0.5.2", - "libc", -] - [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -3879,14 +3392,14 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -3895,36 +3408,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -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.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - [[package]] name = "opaque-debug" version = "0.3.1" @@ -3933,11 +3422,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg-if", "foreign-types", "libc", @@ -3954,7 +3443,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -3963,14 +3452,24 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-src" +version = "300.5.4+3.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" +dependencies = [ + "cc", +] + [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", + "openssl-src", "pkg-config", "vcpkg", ] @@ -3995,16 +3494,21 @@ dependencies = [ ] [[package]] -name = "parking" -version = "2.2.1" +name = "papergrid" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +checksum = "6978128c8b51d8f4080631ceb2302ab51e32cc6e8615f735ee2f83fd269ae3f1" +dependencies = [ + "bytecount", + "fnv", + "unicode-width", +] [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -4012,15 +3516,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -4038,20 +3542,11 @@ 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" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "percentage" @@ -4064,10 +3559,11 @@ dependencies = [ [[package]] name = "photon-api" -version = "0.51.0" -source = "git+https://github.com/lightprotocol/light-protocol?branch=swen-0011-proc#7cf6a9a2b200f1e77f7d39344c8bde69f9597e3e" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e572dba0c255f5b8176f15b9e849330d915a8927804f7f9702d5bbbc70e4a1ad" dependencies = [ - "reqwest 0.12.22", + "reqwest 0.12.28", "serde", "serde_derive", "serde_json", @@ -4093,7 +3589,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -4108,6 +3604,23 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pinocchio" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b971851087bc3699b001954ad02389d50c41405ece3548cbcafc88b3e20017a" + +[[package]] +name = "pinocchio-pubkey" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0225638cadcbebae8932cb7f49cb5da7c15c21beb19f048f05a5ca7d93f065" +dependencies = [ + "five8_const", + "pinocchio", + "sha2-const-stable", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -4128,15 +3641,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -4167,32 +3680,53 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ - "toml_edit", + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.114", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] [[package]] name = "proptest" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.1", - "lazy_static", + "bitflags 2.10.0", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", @@ -4220,22 +3754,7 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", -] - -[[package]] -name = "quanta" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" -dependencies = [ - "crossbeam-utils", - "libc", - "once_cell", - "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", - "web-sys", - "winapi", + "syn 2.0.114", ] [[package]] @@ -4257,9 +3776,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", @@ -4267,9 +3786,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.29", - "socket2 0.5.10", - "thiserror 2.0.12", + "rustls 0.23.36", + "socket2 0.6.1", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -4277,22 +3796,20 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "fastbloom", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", "rustc-hash", - "rustls 0.23.29", + "rustls 0.23.36", "rustls-pki-types", - "rustls-platform-verifier", "slab", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -4300,23 +3817,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.1", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] @@ -4364,7 +3881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -4394,7 +3911,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -4412,16 +3929,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -4439,16 +3956,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.3", -] - -[[package]] -name = "raw-cpuid" -version = "11.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" -dependencies = [ - "bitflags 2.9.1", + "rand_core 0.9.5", ] [[package]] @@ -4456,32 +3964,42 @@ name = "raydium-cp-swap" version = "0.2.0" dependencies = [ "anchor-lang", - "anchor-spl", "arrayref", + "bincode", + "blake3", "bytemuck", + "light-anchor-spl", "light-client", - "light-compressible-client", "light-hasher", - "light-macros", "light-program-test", "light-sdk", - "light-sdk-macros", - "light-sdk-types", - "light-test-utils", + "light-token", "proptest", "quickcheck", "rand 0.9.2", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-keypair", + "solana-msg", + "solana-program", + "solana-program-error", + "solana-pubkey", + "solana-sdk", "solana-security-txt", + "solana-signer", "spl-math", + "spl-token 7.0.0", "spl-token-2022 7.0.0", + "tokio", "uint", ] [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -4489,9 +4007,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -4499,38 +4017,38 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -4540,9 +4058,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -4551,9 +4069,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" @@ -4561,7 +4079,6 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-compression", "base64 0.21.7", "bytes", "encoding_rs", @@ -4577,7 +4094,6 @@ dependencies = [ "js-sys", "log", "mime", - "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -4592,7 +4108,6 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.24.1", - "tokio-util 0.7.15", "tower-service", "url", "wasm-bindgen", @@ -4604,20 +4119,21 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.22" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", "encoding_rs", + "futures-channel", "futures-core", "futures-util", - "h2 0.4.11", - "http 1.3.1", + "h2 0.4.13", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-rustls 0.27.7", "hyper-tls 0.6.0", "hyper-util", @@ -4628,6 +4144,8 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls 0.23.36", "rustls-pki-types", "serde", "serde_json", @@ -4635,6 +4153,7 @@ dependencies = [ "sync_wrapper 1.0.2", "tokio", "tokio-native-tls", + "tokio-rustls 0.26.4", "tower", "tower-http", "tower-service", @@ -4642,21 +4161,22 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots 1.0.5", ] [[package]] name = "reqwest-middleware" -version = "0.2.5" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" +checksum = "57f17d28a6e6acfe1733fe24bcd30774d13bffa4b8a22535b4c8c98423088d4e" dependencies = [ "anyhow", "async-trait", - "http 0.2.12", - "reqwest 0.11.27", + "http 1.4.0", + "reqwest 0.12.28", "serde", - "task-local-extensions", "thiserror 1.0.69", + "tower-service", ] [[package]] @@ -4667,7 +4187,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -4675,9 +4195,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -4694,26 +4214,17 @@ dependencies = [ "semver", ] -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4730,30 +4241,18 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.29" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki 0.103.9", "subtle", "zeroize", ] -[[package]] -name = "rustls-native-certs" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework 3.2.0", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -4765,41 +4264,14 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", ] -[[package]] -name = "rustls-platform-verifier" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" -dependencies = [ - "core-foundation 0.10.1", - "core-foundation-sys", - "jni", - "log", - "once_cell", - "rustls 0.23.29", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki 0.103.4", - "security-framework 3.2.0", - "security-framework-sys", - "webpki-root-certs 0.26.11", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" - [[package]] name = "rustls-webpki" version = "0.101.7" @@ -4812,9 +4284,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -4823,15 +4295,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -4841,35 +4313,17 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "safe_arch" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "same-file" -version = "1.0.6" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4886,9 +4340,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" dependencies = [ "dyn-clone", "ref-cast", @@ -4918,21 +4372,8 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" -dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.10.1", + "bitflags 2.10.0", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -4940,9 +4381,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -4950,16 +4391,17 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -4974,34 +4416,45 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -5027,19 +4480,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.10.0", + "indexmap 2.13.0", "schemars 0.9.0", - "schemars 1.0.4", - "serde", - "serde_derive", + "schemars 1.2.0", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -5047,25 +4499,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.104", -] - -[[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", + "syn 2.0.114", ] [[package]] @@ -5092,6 +4533,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -5129,10 +4576,11 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -5143,22 +4591,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] -name = "siphasher" -version = "0.3.11" +name = "simd-adler32" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "siphasher" -version = "1.0.1" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" @@ -5178,12 +4626,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5206,48 +4654,52 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a8e4aacc7c681419ae63c1de36349d2156d5a4f4ffaea8e507335013e57189" +checksum = "ba71c97fa4d85ce4a1e0e79044ad0406c419382be598c800202903a7688ce71a" dependencies = [ "Inflector", "base64 0.22.1", "bincode", "bs58", "bv", - "lazy_static", "serde", "serde_derive", "serde_json", "solana-account", "solana-account-decoder-client-types", + "solana-address-lookup-table-interface", "solana-clock", - "solana-config-program", + "solana-config-program-client", "solana-epoch-schedule", "solana-fee-calculator", "solana-instruction", + "solana-loader-v3-interface", "solana-nonce", - "solana-program", + "solana-program-option", "solana-program-pack", "solana-pubkey", "solana-rent", "solana-sdk-ids", "solana-slot-hashes", "solana-slot-history", + "solana-stake-interface", "solana-sysvar", - "spl-token", - "spl-token-2022 7.0.0", - "spl-token-group-interface", - "spl-token-metadata-interface", - "thiserror 2.0.12", + "solana-vote-interface", + "spl-generic-token", + "spl-token 8.0.0", + "spl-token-2022 8.0.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "thiserror 2.0.18", "zstd", ] [[package]] name = "solana-account-decoder-client-types" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6329c4f360f5173dd6f65022708486cdd24d302841058e2310945a2502284105" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" dependencies = [ "base64 0.22.1", "bs58", @@ -5261,9 +4713,9 @@ dependencies = [ [[package]] name = "solana-account-info" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" dependencies = [ "bincode", "serde", @@ -5289,31 +4741,6 @@ dependencies = [ "solana-slot-hashes", ] -[[package]] -name = "solana-address-lookup-table-program" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87ae97f2d1b91a9790c1e35dba3f90a4d595d105097ad93fa685cbc034ad0f1" -dependencies = [ - "bincode", - "bytemuck", - "log", - "num-derive 0.4.2", - "num-traits", - "solana-address-lookup-table-interface", - "solana-bincode", - "solana-clock", - "solana-feature-set", - "solana-instruction", - "solana-log-collector", - "solana-packet", - "solana-program-runtime", - "solana-pubkey", - "solana-system-interface", - "solana-transaction-context", - "thiserror 2.0.12", -] - [[package]] name = "solana-atomic-u64" version = "2.2.1" @@ -5325,30 +4752,50 @@ dependencies = [ [[package]] name = "solana-banks-client" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e8b93a73f583fb03c9a43be9185c2e04c8a5df84e3c20fd813f0ff79a12142" +checksum = "68548570c38a021c724b5aa0112f45a54bdf7ff1b041a042848e034a95a96994" dependencies = [ - "borsh 1.5.7", + "borsh 1.6.0", "futures", + "solana-account", "solana-banks-interface", - "solana-program", - "solana-sdk", + "solana-clock", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-signature", + "solana-sysvar", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", "tarpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-serde", ] [[package]] name = "solana-banks-interface" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54bdc2f951d900289a3de58f8fc835fcea67fdaaea390b447e16a8a403a2399" +checksum = "a6d90edc435bf488ef7abed4dcb1f94fa1970102cbabb25688f58417fd948286" dependencies = [ "serde", "serde_derive", - "solana-sdk", + "solana-account", + "solana-clock", + "solana-commitment-config", + "solana-hash", + "solana-message", + "solana-pubkey", + "solana-signature", + "solana-transaction", + "solana-transaction-context", + "solana-transaction-error", "tarpc", ] @@ -5388,9 +4835,9 @@ dependencies = [ [[package]] name = "solana-bn254" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9abc69625158faaab02347370b91c0d8e0fe347bf9287239f0fbe8f5864d91da" +checksum = "4420f125118732833f36facf96a27e7b78314b2d642ba07fa9ffdacd8d79e243" dependencies = [ "ark-bn254 0.4.0", "ark-ec 0.4.2", @@ -5398,7 +4845,7 @@ dependencies = [ "ark-serialize 0.4.2", "bytemuck", "solana-define-syscall", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5408,17 +4855,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" dependencies = [ "borsh 0.10.4", - "borsh 1.5.7", + "borsh 1.6.0", ] [[package]] name = "solana-bpf-loader-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6931e8893b48e3a1c8124938f580fff857d84895582578cc7dbf100dd08d2c8f" +checksum = "b5aec57dcd80d0f6879956cad28854a6eebaed6b346ce56908ea01a9f36ab259" dependencies = [ "bincode", "libsecp256k1", + "num-traits", "qualifier_attr", "scopeguard", "solana-account", @@ -5428,10 +4876,8 @@ dependencies = [ "solana-blake3-hasher", "solana-bn254", "solana-clock", - "solana-compute-budget", "solana-cpi", "solana-curve25519", - "solana-feature-set", "solana-hash", "solana-instruction", "solana-keccak-hasher", @@ -5441,9 +4887,7 @@ dependencies = [ "solana-measure", "solana-packet", "solana-poseidon", - "solana-precompiles", "solana-program-entrypoint", - "solana-program-memory", "solana-program-runtime", "solana-pubkey", "solana-sbpf", @@ -5451,26 +4895,26 @@ dependencies = [ "solana-secp256k1-recover", "solana-sha256-hasher", "solana-stable-layout", + "solana-svm-feature-set", "solana-system-interface", "solana-sysvar", "solana-sysvar-id", "solana-timings", "solana-transaction-context", "solana-type-overrides", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-builtins" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9240641f944ece59e097c9981bdc33b2f519cbd91b9764ff5f62c307d986a3d" +checksum = "6d61a31b63b52b0d268cbcd56c76f50314867d7f8e07a0f2c62ee7c9886e07b2" dependencies = [ - "solana-address-lookup-table-program", + "agave-feature-set", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", - "solana-feature-set", + "solana-hash", "solana-loader-v4-program", "solana-program-runtime", "solana-pubkey", @@ -5484,19 +4928,15 @@ dependencies = [ [[package]] name = "solana-builtins-default-costs" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb6728141dc45bdde9d68b67bb914013be28f94a2aea8bb7131ea8c6161c30e" +checksum = "2ca69a299a6c969b18ea381a02b40c9e4dda04b2af0d15a007c1184c82163bbb" dependencies = [ + "agave-feature-set", "ahash", - "lazy_static", "log", - "qualifier_attr", - "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-compute-budget-program", - "solana-config-program", - "solana-feature-set", "solana-loader-v4-program", "solana-pubkey", "solana-sdk-ids", @@ -5505,52 +4945,6 @@ dependencies = [ "solana-vote-program", ] -[[package]] -name = "solana-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e827416867d988cbba327b6e448ad0bfb85ba44f080c6a02a00aa498c2249c4" -dependencies = [ - "async-trait", - "bincode", - "dashmap 5.5.3", - "futures", - "futures-util", - "indexmap 2.10.0", - "indicatif", - "log", - "quinn", - "rayon", - "solana-account", - "solana-client-traits", - "solana-commitment-config", - "solana-connection-cache", - "solana-epoch-info", - "solana-hash", - "solana-instruction", - "solana-keypair", - "solana-measure", - "solana-message", - "solana-pubkey", - "solana-pubsub-client", - "solana-quic-client", - "solana-quic-definitions", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-rpc-client-nonce-utils", - "solana-signature", - "solana-signer", - "solana-streamer", - "solana-thin-client", - "solana-time-utils", - "solana-tpu-client", - "solana-transaction", - "solana-transaction-error", - "solana-udp-client", - "thiserror 2.0.12", - "tokio", -] - [[package]] name = "solana-client-traits" version = "2.2.1" @@ -5574,9 +4968,9 @@ dependencies = [ [[package]] name = "solana-clock" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c2177a1b9fe8326004f1151a5acd124420b737811080b1035df31349e4d892" +checksum = "1bb482ab70fced82ad3d7d3d87be33d466a3498eb8aa856434ff3c0dfc2e2e31" dependencies = [ "serde", "serde_derive", @@ -5608,42 +5002,42 @@ dependencies = [ [[package]] name = "solana-compute-budget" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e593ce26764fa3366b6d125b9f2455f6cd8d557f86b4f3c7b7c517db6d8f5f" +checksum = "9f4fc63bc2276a1618ca0bfc609da7448534ecb43a1cb387cdf9eaa2dc7bc272" dependencies = [ "solana-fee-structure", - "solana-program-entrypoint", + "solana-program-runtime", ] [[package]] name = "solana-compute-budget-instruction" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240e28cf764d1468f2388fb0d10b70278a64d47277ff552379116ba45d609cd1" +checksum = "503d94430f6d3c5ac1e1fa6a342c1c714d5b03c800999e7b6cf235298f0b5341" dependencies = [ + "agave-feature-set", "log", "solana-borsh", "solana-builtins-default-costs", "solana-compute-budget", "solana-compute-budget-interface", - "solana-feature-set", "solana-instruction", "solana-packet", "solana-pubkey", "solana-sdk-ids", "solana-svm-transaction", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-compute-budget-interface" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5df17b195d312b66dccdde9beec6709766d8230cb4718c4c08854f780d0309" +checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4" dependencies = [ - "borsh 1.5.7", + "borsh 1.6.0", "serde", "serde_derive", "solana-instruction", @@ -5652,60 +5046,24 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfc6b8ea70ed5123412655ed15e7e0e29f06a7d5b82eb2572bee608d7755afb7" +checksum = "072b02beed1862c6b7b7a8a699379594c4470a9371c711856a0a3c266dcf57e5" dependencies = [ - "qualifier_attr", "solana-program-runtime", ] [[package]] -name = "solana-config-program" -version = "2.2.4" +name = "solana-config-program-client" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2417094a8c5c2d60812a5bd6f0bd31bdefc49479826c10347a85d217e088c964" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" dependencies = [ "bincode", - "chrono", + "borsh 0.10.4", + "kaigan", "serde", - "serde_derive", - "solana-account", - "solana-bincode", - "solana-instruction", - "solana-log-collector", - "solana-packet", - "solana-program-runtime", - "solana-pubkey", - "solana-sdk-ids", - "solana-short-vec", - "solana-stake-interface", - "solana-system-interface", - "solana-transaction-context", -] - -[[package]] -name = "solana-connection-cache" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ad0b507b4044e2690915c9aa69eacfd51b1fa55e4deeca662ee5cff7d7d1f4" -dependencies = [ - "async-trait", - "bincode", - "crossbeam-channel", - "futures-util", - "indexmap 2.10.0", - "log", - "rand 0.8.5", - "rayon", - "solana-keypair", - "solana-measure", - "solana-metrics", - "solana-net-utils", - "solana-time-utils", - "solana-transaction-error", - "thiserror 2.0.12", - "tokio", + "solana-program", ] [[package]] @@ -5724,16 +5082,16 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3d15f1a893ced38529d44d7fe0d4348dc38c28fea13b6d6be5d13d438a441f" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" dependencies = [ "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", "solana-define-syscall", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5747,9 +5105,9 @@ dependencies = [ [[package]] name = "solana-define-syscall" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf784bb2cb3e02cac9801813c30187344228d2ae952534902108f6150573a33d" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" [[package]] name = "solana-derivation-path" @@ -5807,7 +5165,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c5fd2662ae7574810904585fd443545ed2b568dbd304b25a31e79ccc76e81b" dependencies = [ - "siphasher 0.3.11", + "siphasher", "solana-hash", "solana-pubkey", ] @@ -5843,14 +5201,14 @@ dependencies = [ "solana-pubkey", "solana-sdk-ids", "solana-system-interface", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-feature-gate-interface" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9c7fbf3e58b64a667c5f35e90af580538a95daea7001ff7806c0662d301bdf" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" dependencies = [ "bincode", "serde", @@ -5867,9 +5225,9 @@ dependencies = [ [[package]] name = "solana-feature-set" -version = "2.2.1" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e1d3b52b4a014efeaaab67f14e40af3972a4be61c523d612860db8e3145529" +checksum = "93b93971e289d6425f88e6e3cb6668c4b05df78b3c518c249be55ced8efd6b6d" dependencies = [ "ahash", "lazy_static", @@ -5881,11 +5239,11 @@ dependencies = [ [[package]] name = "solana-fee" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c14eaaa9d099e4510c9105522d97778cd66c3d401f0d68eebcf43179a1bf094" +checksum = "16beda37597046b1edd1cea6fa7caaed033c091f99ec783fe59c82828bc2adb8" dependencies = [ - "solana-feature-set", + "agave-feature-set", "solana-fee-structure", "solana-svm-transaction", ] @@ -5903,21 +5261,21 @@ dependencies = [ [[package]] name = "solana-fee-structure" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f45f94a88efdb512805563181dfa1c85c60a21b6e6d602bf24a2ea88f9399d6e" +checksum = "33adf673581c38e810bf618f745bf31b683a0a4a4377682e6aaac5d9a058dd4e" dependencies = [ "serde", "serde_derive", "solana-message", - "solana-native-token", + "solana-native-token 2.3.0", ] [[package]] name = "solana-genesis-config" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968dabd2b92d57131473eddbd475339da530e14f54397386abf303de3a2595a2" +checksum = "b3725085d47b96d37fef07a29d78d2787fc89a0b9004c66eed7753d1e554989f" dependencies = [ "bincode", "chrono", @@ -5933,7 +5291,6 @@ dependencies = [ "solana-inflation", "solana-keypair", "solana-logger", - "solana-native-token", "solana-poh-config", "solana-pubkey", "solana-rent", @@ -5956,14 +5313,14 @@ dependencies = [ [[package]] name = "solana-hash" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf7bcb14392900fe02e4e34e90234fbf0c673d4e327888410ba99fa2ba0f4e99" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" dependencies = [ - "borsh 1.5.7", - "bs58", + "borsh 1.6.0", "bytemuck", "bytemuck_derive", + "five8", "js-sys", "serde", "serde_derive", @@ -5982,29 +5339,20 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "solana-inline-spl" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed78e6709851bb3fa8a0acb1ee40fbffa888049d042ca132d6ccb8e0b313ac72" -dependencies = [ - "bytemuck", - "solana-pubkey", -] - [[package]] name = "solana-instruction" -version = "2.2.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" dependencies = [ "bincode", - "borsh 1.5.7", - "getrandom 0.2.16", + "borsh 1.6.0", + "getrandom 0.2.17", "js-sys", "num-traits", "serde", "serde_derive", + "serde_json", "solana-define-syscall", "solana-pubkey", "wasm-bindgen", @@ -6016,7 +5364,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "solana-account-info", "solana-instruction", "solana-program-error", @@ -6041,13 +5389,13 @@ dependencies = [ [[package]] name = "solana-keypair" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dbb7042c2e0c561afa07242b2099d55c57bd1b1da3b6476932197d84e15e3e4" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" dependencies = [ - "bs58", "ed25519-dalek", "ed25519-dalek-bip32", + "five8", "rand 0.7.3", "solana-derivation-path", "solana-pubkey", @@ -6087,9 +5435,9 @@ dependencies = [ [[package]] name = "solana-loader-v3-interface" -version = "3.0.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" dependencies = [ "serde", "serde_bytes", @@ -6117,16 +5465,15 @@ dependencies = [ [[package]] name = "solana-loader-v4-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0298bf161e18b146230b15e8fa57bd170a05342ab9c1fd996b0241c0f016c2" +checksum = "a6ab01855d851fa2fb6034b0d48de33d77d5c5f5fb4b0353d8e4a934cc03d48a" dependencies = [ "log", "qualifier_attr", "solana-account", "solana-bincode", "solana-bpf-loader-program", - "solana-compute-budget", "solana-instruction", "solana-loader-v3-interface", "solana-loader-v4-interface", @@ -6143,9 +5490,9 @@ dependencies = [ [[package]] name = "solana-log-collector" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d03bf4c676117575be755296e8f21233d74cd28dca227c42e97e86219a27193" +checksum = "9d945b1cf5bf7cbd6f5b78795beda7376370c827640df43bb2a1c17b492dc106" dependencies = [ "log", ] @@ -6165,15 +5512,15 @@ dependencies = [ [[package]] name = "solana-measure" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b17ee553110d2bfc454b8784840a4b75867e123d3816e13046989463fed2c6b" +checksum = "11dcd67cd2ae6065e494b64e861e0498d046d95a61cbbf1ae3d58be1ea0f42ed" [[package]] name = "solana-message" -version = "2.2.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "268486ba8a294ed22a4d7c1ec05f540c3dbe71cfa7c6c54b6d4d13668d895678" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" dependencies = [ "bincode", "blake3", @@ -6194,20 +5541,18 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98b79bd642efa8388791fef7a900bfeb48865669148d523fba041fa7e407312f" +checksum = "0375159d8460f423d39e5103dcff6e07796a5ec1850ee1fcfacfd2482a8f34b5" dependencies = [ "crossbeam-channel", "gethostname", - "lazy_static", "log", - "reqwest 0.11.27", - "solana-clock", + "reqwest 0.12.28", "solana-cluster-type", "solana-sha256-hasher", "solana-time-utils", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -6221,31 +5566,15 @@ dependencies = [ [[package]] name = "solana-native-token" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e9de00960197412e4be3902a6cd35e60817c511137aca6c34c66cd5d4017ec" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" [[package]] -name = "solana-net-utils" -version = "2.2.4" +name = "solana-native-token" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9db57e121ca1577fb5578d916bed549632be0e54a2098e8325980ac724d283" -dependencies = [ - "anyhow", - "bincode", - "bytes", - "crossbeam-channel", - "itertools 0.12.1", - "log", - "nix", - "rand 0.8.5", - "serde", - "serde_derive", - "socket2 0.5.10", - "solana-serde", - "tokio", - "url", -] +checksum = "ae8dd4c280dca9d046139eb5b7a5ac9ad10403fbd64964c7d7571214950d758f" [[package]] name = "solana-nonce" @@ -6305,45 +5634,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "004f2d2daf407b3ec1a1ca5ec34b3ccdfd6866dd2d3c7d0715004a96e4b6d127" dependencies = [ "bincode", - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg_eval", "serde", "serde_derive", "serde_with", ] -[[package]] -name = "solana-perf" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b87939c18937f8bfad6028779a02fa123b27e986fb2c55fbbf683952a0e4932" -dependencies = [ - "ahash", - "bincode", - "bv", - "caps", - "curve25519-dalek 4.1.3", - "dlopen2", - "fnv", - "lazy_static", - "libc", - "log", - "nix", - "rand 0.8.5", - "rayon", - "serde", - "solana-hash", - "solana-message", - "solana-metrics", - "solana-packet", - "solana-pubkey", - "solana-rayon-threadlimit", - "solana-sdk-ids", - "solana-short-vec", - "solana-signature", - "solana-time-utils", -] - [[package]] name = "solana-poh-config" version = "2.2.1" @@ -6356,14 +5653,14 @@ dependencies = [ [[package]] name = "solana-poseidon" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2908b48b3828bc04b752d1ff36122f5a06de043258da88df5f8ce64791d208" +checksum = "cbac4eb90016eeb1d37fa36e592d3a64421510c49666f81020736611c319faff" dependencies = [ "ark-bn254 0.4.0", "light-poseidon 0.2.0", "solana-define-syscall", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -6378,9 +5675,9 @@ dependencies = [ [[package]] name = "solana-precompiles" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a460ab805ec063802105b463ecb5eb02c3ffe469e67a967eea8a6e778e0bc06" +checksum = "36e92768a57c652edb0f5d1b30a7d0bc64192139c517967c18600debe9ae3832" dependencies = [ "lazy_static", "solana-ed25519-program", @@ -6406,24 +5703,24 @@ dependencies = [ [[package]] name = "solana-program" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586469467e93ceb79048f8d8e3a619bf61d05396ee7de95cb40280301a589d05" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" dependencies = [ "bincode", "blake3", "borsh 0.10.4", - "borsh 1.5.7", + "borsh 1.6.0", "bs58", "bytemuck", "console_error_panic_hook", "console_log", - "getrandom 0.2.16", + "getrandom 0.2.17", "lazy_static", "log", "memoffset", "num-bigint 0.4.6", - "num-derive 0.4.2", + "num-derive", "num-traits", "rand 0.8.5", "serde", @@ -6455,7 +5752,7 @@ dependencies = [ "solana-loader-v4-interface", "solana-message", "solana-msg", - "solana-native-token", + "solana-native-token 2.3.0", "solana-nonce", "solana-program-entrypoint", "solana-program-error", @@ -6480,15 +5777,15 @@ dependencies = [ "solana-sysvar", "solana-sysvar-id", "solana-vote-interface", - "thiserror 2.0.12", + "thiserror 2.0.18", "wasm-bindgen", ] [[package]] name = "solana-program-entrypoint" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473ffe73c68d93e9f2aa726ad2985fe52760052709aaab188100a42c618060ec" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" dependencies = [ "solana-account-info", "solana-msg", @@ -6502,7 +5799,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" dependencies = [ - "borsh 1.5.7", + "borsh 1.6.0", "num-traits", "serde", "serde_derive", @@ -6514,11 +5811,10 @@ dependencies = [ [[package]] name = "solana-program-memory" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0268f6c89825fb634a34bd0c3b8fdaeaecfc3728be1d622a8ee6dd577b60d4" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" dependencies = [ - "num-traits", "solana-define-syscall", ] @@ -6539,9 +5835,9 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce0a9acc6049c2ae8a2a2dd0b63269ab1a6d8fab4dead1aae75a9bcdd4aa6f05" +checksum = "5653001e07b657c9de6f0417cf9add1cf4325903732c480d415655e10cc86704" dependencies = [ "base64 0.22.1", "bincode", @@ -6553,45 +5849,47 @@ dependencies = [ "serde", "solana-account", "solana-clock", - "solana-compute-budget", "solana-epoch-rewards", "solana-epoch-schedule", - "solana-feature-set", + "solana-fee-structure", "solana-hash", "solana-instruction", "solana-last-restart-slot", "solana-log-collector", "solana-measure", "solana-metrics", - "solana-precompiles", + "solana-program-entrypoint", "solana-pubkey", "solana-rent", "solana-sbpf", "solana-sdk-ids", "solana-slot-hashes", "solana-stable-layout", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-system-interface", "solana-sysvar", "solana-sysvar-id", "solana-timings", "solana-transaction-context", "solana-type-overrides", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-pubkey" -version = "2.2.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" dependencies = [ "borsh 0.10.4", - "borsh 1.5.7", - "bs58", + "borsh 1.6.0", "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", + "five8", "five8_const", - "getrandom 0.2.16", + "getrandom 0.2.17", "js-sys", "num-traits", "rand 0.8.5", @@ -6605,83 +5903,15 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "solana-pubsub-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d219147fd3a6753dc4819578fb6830c082a7c26b1559fab0f240fcf11f4e39" -dependencies = [ - "crossbeam-channel", - "futures-util", - "log", - "reqwest 0.11.27", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder-client-types", - "solana-clock", - "solana-pubkey", - "solana-rpc-client-api", - "solana-signature", - "thiserror 2.0.12", - "tokio", - "tokio-stream", - "tokio-tungstenite", - "tungstenite", - "url", -] - -[[package]] -name = "solana-quic-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769d66df4ab445ab689ab2c4f10135dfe80576859b4fea1cae7d9bdd7985e4e2" -dependencies = [ - "async-lock", - "async-trait", - "futures", - "itertools 0.12.1", - "lazy_static", - "log", - "quinn", - "quinn-proto", - "rustls 0.23.29", - "solana-connection-cache", - "solana-keypair", - "solana-measure", - "solana-metrics", - "solana-net-utils", - "solana-pubkey", - "solana-quic-definitions", - "solana-rpc-client-api", - "solana-signer", - "solana-streamer", - "solana-tls-utils", - "solana-transaction-error", - "thiserror 2.0.12", - "tokio", -] - [[package]] name = "solana-quic-definitions" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e606feac5110eb5d8afaa43ccaeea3ec49ccec36773387930b5ba545e745aea2" +checksum = "fbf0d4d5b049eb1d0c35f7b18f305a27c8986fc5c0c9b383e97adaa35334379e" dependencies = [ "solana-keypair", ] -[[package]] -name = "solana-rayon-threadlimit" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bf3ad7091b26c9bd0ebabff6ac4d825c88ecf2eafdb83de30dffda80ffc2f17" -dependencies = [ - "lazy_static", - "num_cpus", -] - [[package]] name = "solana-rent" version = "2.2.1" @@ -6697,9 +5927,9 @@ dependencies = [ [[package]] name = "solana-rent-collector" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c1e19f5d5108b0d824244425e43bc78bbb9476e2199e979b0230c9f632d3bf4" +checksum = "127e6dfa51e8c8ae3aa646d8b2672bc4ac901972a338a9e1cd249e030564fb9d" dependencies = [ "serde", "serde_derive", @@ -6724,9 +5954,9 @@ dependencies = [ [[package]] name = "solana-reserved-account-keys" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b293f4246626c0e0a991531f08848a713ada965612e99dc510963f04d12cae7" +checksum = "e4b22ea19ca2a3f28af7cd047c914abf833486bf7a7c4a10fc652fff09b385b1" dependencies = [ "lazy_static", "solana-feature-set", @@ -6746,17 +5976,18 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f1809a424bb8d90aa40990451593cde7e734a060fb52b35e475db585450578" +checksum = "b8d3161ac0918178e674c1f7f1bfac40de3e7ed0383bd65747d63113c156eaeb" dependencies = [ "async-trait", "base64 0.22.1", "bincode", "bs58", + "futures", "indicatif", "log", - "reqwest 0.11.27", + "reqwest 0.12.28", "reqwest-middleware", "semver", "serde", @@ -6779,55 +6010,56 @@ dependencies = [ "solana-transaction-error", "solana-transaction-status-client-types", "solana-version", + "solana-vote-interface", "tokio", ] [[package]] name = "solana-rpc-client-api" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2eb4fe573cd2d59d8672f0d8ac65f64e70c948b36cf97218b9aeb80dca3329" +checksum = "2dbc138685c79d88a766a8fd825057a74ea7a21e1dd7f8de275ada899540fff7" dependencies = [ "anyhow", - "base64 0.22.1", - "bs58", "jsonrpc-core", - "reqwest 0.11.27", + "reqwest 0.12.28", "reqwest-middleware", - "semver", "serde", "serde_derive", "serde_json", - "solana-account", "solana-account-decoder-client-types", "solana-clock", - "solana-commitment-config", - "solana-fee-calculator", - "solana-inflation", - "solana-inline-spl", - "solana-pubkey", + "solana-rpc-client-types", "solana-signer", "solana-transaction-error", "solana-transaction-status-client-types", - "solana-version", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] -name = "solana-rpc-client-nonce-utils" -version = "2.2.4" +name = "solana-rpc-client-types" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2712d22c58616762ad8e02fc18556eaf7be4104d5e56b11a2b8aa892c7de2a08" +checksum = "8ea428a81729255d895ea47fba9b30fd4dacbfe571a080448121bd0592751676" dependencies = [ + "base64 0.22.1", + "bs58", + "semver", + "serde", + "serde_derive", + "serde_json", "solana-account", + "solana-account-decoder-client-types", + "solana-clock", "solana-commitment-config", - "solana-hash", - "solana-message", - "solana-nonce", + "solana-fee-calculator", + "solana-inflation", "solana-pubkey", - "solana-rpc-client", - "solana-sdk-ids", - "thiserror 2.0.12", + "solana-transaction-error", + "solana-transaction-status-client-types", + "solana-version", + "spl-generic-token", + "thiserror 2.0.18", ] [[package]] @@ -6838,26 +6070,26 @@ checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" [[package]] name = "solana-sbpf" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a3ce7a0f4d6830124ceb2c263c36d1ee39444ec70146eb49b939e557e72b96" +checksum = "474a2d95dc819898ded08d24f29642d02189d3e1497bbb442a92a3997b7eb55f" dependencies = [ "byteorder", - "combine 3.8.1", + "combine", "hash32", "libc", "log", "rand 0.8.5", "rustc-demangle", - "thiserror 1.0.69", + "thiserror 2.0.18", "winapi", ] [[package]] name = "solana-sdk" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4808e8d7f3c931657e615042d4176b423e66f64dc99e3dc3c735a197e512029b" +checksum = "8cc0e4a7635b902791c44b6581bfb82f3ada32c5bc0929a64f39fe4bb384c86a" dependencies = [ "bincode", "bs58", @@ -6884,7 +6116,7 @@ dependencies = [ "solana-instruction", "solana-keypair", "solana-message", - "solana-native-token", + "solana-native-token 2.3.0", "solana-nonce-account", "solana-offchain-message", "solana-packet", @@ -6920,7 +6152,7 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-validator-exit", - "thiserror 2.0.12", + "thiserror 2.0.18", "wasm-bindgen", ] @@ -6942,14 +6174,14 @@ dependencies = [ "bs58", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "solana-secp256k1-program" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a1caa972414cc78122c32bdae65ac5fe89df7db598585a5cde19d16a20280a" +checksum = "f19833e4bc21558fe9ec61f239553abe7d05224347b57d65c2218aeeb82d6149" dependencies = [ "bincode", "digest 0.10.7", @@ -6961,6 +6193,7 @@ dependencies = [ "solana-instruction", "solana-precompile-error", "solana-sdk-ids", + "solana-signature", ] [[package]] @@ -6969,17 +6202,17 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" dependencies = [ - "borsh 1.5.7", + "borsh 1.6.0", "libsecp256k1", "solana-define-syscall", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-secp256r1-program" -version = "2.2.3" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf903cbdc36a161533812f90acfccdb434ed48982bd5dd71f3217930572c4a80" +checksum = "ce0ae46da3071a900f02d367d99b2f3058fe2e90c5062ac50c4f20cfedad8f0f" dependencies = [ "bytemuck", "openssl", @@ -6991,9 +6224,12 @@ dependencies = [ [[package]] name = "solana-security-txt" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" +checksum = "156bb61a96c605fa124e052d630dba2f6fb57e08c7d15b757e1e958b3ed7b3fe" +dependencies = [ + "hashbrown 0.15.2", +] [[package]] name = "solana-seed-derivable" @@ -7026,9 +6262,9 @@ dependencies = [ [[package]] name = "solana-serde-varint" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc07d00200d82e6def2f7f7a45738e3406b17fe54a18adcf0defa16a97ccadb" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" dependencies = [ "serde", ] @@ -7046,9 +6282,9 @@ dependencies = [ [[package]] name = "solana-sha256-hasher" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" dependencies = [ "sha2 0.10.9", "solana-define-syscall", @@ -7077,12 +6313,12 @@ dependencies = [ [[package]] name = "solana-signature" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47d251c8f3dc015f320b4161daac7f108156c837428e5a8cc61136d25beb11d6" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" dependencies = [ - "bs58", "ed25519-dalek", + "five8", "rand 0.8.5", "serde", "serde-big-array", @@ -7144,7 +6380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ "borsh 0.10.4", - "borsh 1.5.7", + "borsh 1.6.0", "num-traits", "serde", "serde_derive", @@ -7160,21 +6396,21 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b140dad8a60e40c381a0a359a350d37d51827d02ceb623acf8b942c04f3f3e6" +checksum = "500e9b9d11573f12de91e94f9c4459882cd5ffc692776af49b610d6fcc0b167f" dependencies = [ + "agave-feature-set", "bincode", "log", "solana-account", "solana-bincode", "solana-clock", - "solana-config-program", - "solana-feature-set", + "solana-config-program-client", "solana-genesis-config", "solana-instruction", "solana-log-collector", - "solana-native-token", + "solana-native-token 2.3.0", "solana-packet", "solana-program-runtime", "solana-pubkey", @@ -7188,57 +6424,27 @@ dependencies = [ ] [[package]] -name = "solana-streamer" -version = "2.2.4" +name = "solana-svm-callback" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8251a832b9f849e32266e2ebc14dba374c6c58d64e8b1ea9e9d95e836a53fe6" +checksum = "7cef9f7d5cfb5d375081a6c8ad712a6f0e055a15890081f845acf55d8254a7a2" dependencies = [ - "async-channel", - "bytes", - "crossbeam-channel", - "dashmap 5.5.3", - "futures", - "futures-util", - "governor 0.6.3", - "histogram", - "indexmap 2.10.0", - "itertools 0.12.1", - "libc", - "log", - "nix", - "pem", - "percentage", - "quinn", - "quinn-proto", - "rand 0.8.5", - "rustls 0.23.29", - "smallvec", - "socket2 0.5.10", - "solana-keypair", - "solana-measure", - "solana-metrics", - "solana-net-utils", - "solana-packet", - "solana-perf", + "solana-account", + "solana-precompile-error", "solana-pubkey", - "solana-quic-definitions", - "solana-signature", - "solana-signer", - "solana-time-utils", - "solana-tls-utils", - "solana-transaction-error", - "solana-transaction-metrics-tracker", - "thiserror 2.0.12", - "tokio", - "tokio-util 0.7.15", - "x509-parser", ] +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + [[package]] name = "solana-svm-transaction" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1da9eb37e6ced0215a5e44df4ed1f3b885cf349156cbbf99197680cb7eaccf5f" +checksum = "ab717b9539375ebb088872c6c87d1d8832d19f30f154ecc530154d23f60a6f0c" dependencies = [ "solana-hash", "solana-message", @@ -7266,9 +6472,9 @@ dependencies = [ [[package]] name = "solana-system-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6321fd5380961387ef4633a98c109ac7f978667ceab2a38d0a699d6ddb2fc57a" +checksum = "23ca36cef39aea7761be58d4108a56a2e27042fb1e913355fdb142a05fc7eab7" dependencies = [ "bincode", "log", @@ -7276,6 +6482,7 @@ dependencies = [ "serde_derive", "solana-account", "solana-bincode", + "solana-fee-calculator", "solana-instruction", "solana-log-collector", "solana-nonce", @@ -7307,9 +6514,9 @@ dependencies = [ [[package]] name = "solana-sysvar" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6b44740d7f0c9f375d045c165bc0aab4a90658f92d6835aeb0649afaeaff9a" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" dependencies = [ "base64 0.22.1", "bincode", @@ -7352,35 +6559,6 @@ dependencies = [ "solana-sdk-ids", ] -[[package]] -name = "solana-thin-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f6e417c23af670d7861ef74feae3c556d47ea9e5f64c664cfcf6d254f43e1a" -dependencies = [ - "bincode", - "log", - "rayon", - "solana-account", - "solana-client-traits", - "solana-clock", - "solana-commitment-config", - "solana-connection-cache", - "solana-epoch-info", - "solana-hash", - "solana-instruction", - "solana-keypair", - "solana-message", - "solana-pubkey", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-signer", - "solana-system-interface", - "solana-transaction", - "solana-transaction-error", -] - [[package]] name = "solana-time-utils" version = "2.2.1" @@ -7389,67 +6567,20 @@ checksum = "6af261afb0e8c39252a04d026e3ea9c405342b08c871a2ad8aa5448e068c784c" [[package]] name = "solana-timings" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224f93327d9d3178a30cd6c057e1ac6ca85e95287dd7355064dfa6b9c49f5671" +checksum = "7c49b842dfc53c1bf9007eaa6730296dea93b4fce73f457ce1080af43375c0d6" dependencies = [ "eager", "enum-iterator", "solana-pubkey", ] -[[package]] -name = "solana-tls-utils" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec21c6c242ee93642aa50b829f5727470cdbdf6b461fb7323fe4bc31d1b54c08" -dependencies = [ - "rustls 0.23.29", - "solana-keypair", - "solana-pubkey", - "solana-signer", - "x509-parser", -] - -[[package]] -name = "solana-tpu-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e3ff3c8ece22043d96758f980d95558d50792d827d1457c2e06d9daaa7ff5" -dependencies = [ - "async-trait", - "bincode", - "futures-util", - "indexmap 2.10.0", - "indicatif", - "log", - "rayon", - "solana-client-traits", - "solana-clock", - "solana-commitment-config", - "solana-connection-cache", - "solana-epoch-info", - "solana-measure", - "solana-message", - "solana-net-utils", - "solana-pubkey", - "solana-pubsub-client", - "solana-quic-definitions", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-signer", - "solana-transaction", - "solana-transaction-error", - "thiserror 2.0.12", - "tokio", -] - [[package]] name = "solana-transaction" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "753b3e9afed170e4cfc0ea1e87b5dfdc6d4a50270869414edd24c6ea1f529b29" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" dependencies = [ "bincode", "serde", @@ -7462,7 +6593,6 @@ dependencies = [ "solana-message", "solana-precompiles", "solana-pubkey", - "solana-reserved-account-keys", "solana-sanitize", "solana-sdk-ids", "solana-short-vec", @@ -7475,18 +6605,19 @@ dependencies = [ [[package]] name = "solana-transaction-context" -version = "2.2.1" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5022de04cbba05377f68bf848c8c1322ead733f88a657bf792bb40f3257b8218" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" dependencies = [ "bincode", "serde", "serde_derive", "solana-account", "solana-instruction", + "solana-instructions-sysvar", "solana-pubkey", "solana-rent", - "solana-signature", + "solana-sdk-ids", ] [[package]] @@ -7501,69 +6632,55 @@ dependencies = [ "solana-sanitize", ] -[[package]] -name = "solana-transaction-metrics-tracker" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e40670c0780af24e73551be1fadf2306f61ed13f538ff3933846dab813b06d" -dependencies = [ - "base64 0.22.1", - "bincode", - "lazy_static", - "log", - "rand 0.8.5", - "solana-packet", - "solana-perf", - "solana-short-vec", - "solana-signature", -] - [[package]] name = "solana-transaction-status" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05fc20dd8feb089562b113a80115dab32b22fc64d63ca45c14d7b71e5e98d67" +checksum = "135f92f4192cc68900c665becf97fc0a6500ae5a67ff347bf2cbc20ecfefa821" dependencies = [ "Inflector", + "agave-reserved-account-keys", "base64 0.22.1", "bincode", - "borsh 1.5.7", + "borsh 1.6.0", "bs58", - "lazy_static", "log", "serde", "serde_derive", "serde_json", "solana-account-decoder", + "solana-address-lookup-table-interface", "solana-clock", "solana-hash", "solana-instruction", "solana-loader-v2-interface", + "solana-loader-v3-interface", "solana-message", - "solana-program", + "solana-program-option", "solana-pubkey", - "solana-reserved-account-keys", "solana-reward-info", "solana-sdk-ids", "solana-signature", + "solana-stake-interface", "solana-system-interface", "solana-transaction", "solana-transaction-error", "solana-transaction-status-client-types", - "spl-associated-token-account", + "solana-vote-interface", + "spl-associated-token-account 7.0.0", "spl-memo", - "spl-token", - "spl-token-2022 7.0.0", - "spl-token-group-interface", - "spl-token-metadata-interface", - "thiserror 2.0.12", + "spl-token 8.0.0", + "spl-token-2022 8.0.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "thiserror 2.0.18", ] [[package]] name = "solana-transaction-status-client-types" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1458fc750d0df4439bb4c1b418a4fe61afbd2e83963e452256eca99dc0c1cf76" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" dependencies = [ "base64 0.22.1", "bincode", @@ -7579,35 +6696,18 @@ dependencies = [ "solana-transaction", "solana-transaction-context", "solana-transaction-error", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-type-overrides" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26d927bf3ed2f2b6b06a0f409dd8d6b1ad1af73cbba337e9471d05d42f026c9" +checksum = "41d80c44761eb398a157d809a04840865c347e1831ae3859b6100c0ee457bc1a" dependencies = [ - "lazy_static", "rand 0.8.5", ] -[[package]] -name = "solana-udp-client" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c37955cc627be2745e29ce326fd1b51739e499445b5e2b5fec687ed8ec581e34" -dependencies = [ - "async-trait", - "solana-connection-cache", - "solana-keypair", - "solana-net-utils", - "solana-streamer", - "solana-transaction-error", - "thiserror 2.0.12", - "tokio", -] - [[package]] name = "solana-validator-exit" version = "2.2.1" @@ -7616,26 +6716,27 @@ checksum = "7bbf6d7a3c0b28dd5335c52c0e9eae49d0ae489a8f324917faf0ded65a812c1d" [[package]] name = "solana-version" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374dea09855d46655c776256dda9cc3c854cc70fd923ef22ba0805bc83ca7bfd" +checksum = "3324d46c7f7b7f5d34bf7dc71a2883bdc072c7b28ca81d0b2167ecec4cf8da9f" dependencies = [ + "agave-feature-set", + "rand 0.8.5", "semver", "serde", "serde_derive", - "solana-feature-set", "solana-sanitize", "solana-serde-varint", ] [[package]] name = "solana-vote-interface" -version = "2.2.1" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4507bb9d071fb81cfcf676f12fba3db4098f764524ef0b5567d671a81d41f3e" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" dependencies = [ "bincode", - "num-derive 0.4.2", + "num-derive", "num-traits", "serde", "serde_derive", @@ -7654,13 +6755,14 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0289c18977992907d361ca94c86cf45fd24cb41169fa03eb84947779e22933f" +checksum = "908d0e72c8b83e48762eb3e8c9114497cf4b1d66e506e360c46aba9308e71299" dependencies = [ + "agave-feature-set", "bincode", "log", - "num-derive 0.4.2", + "num-derive", "num-traits", "serde", "serde_derive", @@ -7668,7 +6770,6 @@ dependencies = [ "solana-bincode", "solana-clock", "solana-epoch-schedule", - "solana-feature-set", "solana-hash", "solana-instruction", "solana-keypair", @@ -7683,17 +6784,18 @@ dependencies = [ "solana-transaction", "solana-transaction-context", "solana-vote-interface", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] name = "solana-zk-elgamal-proof-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a96b0ad864cc4d2156dbf0c4d7cadac4140ae13ebf7e856241500f74eca46f4" +checksum = "70cea14481d8efede6b115a2581f27bc7c6fdfba0752c20398456c3ac1245fc4" dependencies = [ + "agave-feature-set", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-instruction", "solana-log-collector", @@ -7704,9 +6806,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71db02a2e496c58840077c96dd4ede61894a4e6053853cca6dcddbb73200fb77" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -7716,9 +6818,8 @@ dependencies = [ "curve25519-dalek 4.1.3", "itertools 0.12.1", "js-sys", - "lazy_static", "merlin", - "num-derive 0.4.2", + "num-derive", "num-traits", "rand 0.8.5", "serde", @@ -7734,21 +6835,21 @@ dependencies = [ "solana-signature", "solana-signer", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.18", "wasm-bindgen", "zeroize", ] [[package]] name = "solana-zk-token-proof-program" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c540a4f7df1300dc6087f0cbb271b620dd55e131ea26075bb52ba999be3105f0" +checksum = "579752ad6ea2a671995f13c763bf28288c3c895cb857a518cc4ebab93c9a8dde" dependencies = [ + "agave-feature-set", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", - "solana-feature-set", "solana-instruction", "solana-log-collector", "solana-program-runtime", @@ -7758,9 +6859,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "2.2.4" +version = "2.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4debebedfebfd4a188a7ac3dd0a56e86368417c35891d6f3c35550b46bfbc0" +checksum = "5055e5df94abd5badf4f947681c893375bdb6f8f543c05d2a7ab9647a6a9d205" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -7769,9 +6870,8 @@ dependencies = [ "bytemuck_derive", "curve25519-dalek 4.1.3", "itertools 0.12.1", - "lazy_static", "merlin", - "num-derive 0.4.2", + "num-derive", "num-traits", "rand 0.8.5", "serde", @@ -7788,33 +6888,40 @@ dependencies = [ "solana-signature", "solana-signer", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] [[package]] -name = "spinning_top" -version = "0.3.0" +name = "spl-associated-token-account" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +checksum = "76fee7d65013667032d499adc3c895e286197a35a0d3a4643c80e7fd3e9969e3" dependencies = [ - "lock_api", + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token 7.0.0", + "spl-token-2022 6.0.0", + "thiserror 1.0.69", ] [[package]] name = "spl-associated-token-account" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76fee7d65013667032d499adc3c895e286197a35a0d3a4643c80e7fd3e9969e3" +checksum = "ae179d4a26b3c7a20c839898e6aed84cb4477adf108a366c95532f058aea041b" dependencies = [ - "borsh 1.5.7", - "num-derive 0.4.2", + "borsh 1.6.0", + "num-derive", "num-traits", "solana-program", "spl-associated-token-account-client", - "spl-token", - "spl-token-2022 6.0.0", - "thiserror 1.0.69", + "spl-token 8.0.0", + "spl-token-2022 8.0.1", + "thiserror 2.0.18", ] [[package]] @@ -7847,19 +6954,19 @@ checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "spl-discriminator-syn" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" dependencies = [ "proc-macro2", "quote", "sha2 0.10.9", - "syn 2.0.104", + "syn 2.0.114", "thiserror 1.0.69", ] @@ -7873,7 +6980,40 @@ dependencies = [ "solana-program", "solana-zk-sdk", "spl-pod", - "spl-token-confidential-transfer-proof-extraction", + "spl-token-confidential-transfer-proof-extraction 0.2.1", +] + +[[package]] +name = "spl-elgamal-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65edfeed09cd4231e595616aa96022214f9c9d2be02dea62c2b30d5695a6833a" +dependencies = [ + "bytemuck", + "solana-account-info", + "solana-cpi", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction 0.3.0", +] + +[[package]] +name = "spl-generic-token" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" +dependencies = [ + "bytemuck", + "solana-pubkey", ] [[package]] @@ -7882,8 +7022,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5cc5a6cc7a4f0cf7813ce44153bba73280909f697d7f6baf7b9f223a255e7887" dependencies = [ - "borsh 1.5.7", - "num-derive 0.4.2", + "borsh 1.6.0", + "num-derive", "num-traits", "solana-program", "thiserror 1.0.69", @@ -7906,14 +7046,14 @@ dependencies = [ [[package]] name = "spl-pod" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a7d5950993e1ff2680bd989df298eeb169367fb2f9deeef1f132de6e4e8016" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" dependencies = [ - "borsh 1.5.7", + "borsh 1.6.0", "bytemuck", "bytemuck_derive", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-decode-error", "solana-msg", @@ -7921,7 +7061,7 @@ dependencies = [ "solana-program-option", "solana-pubkey", "solana-zk-sdk", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -7930,13 +7070,28 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d39b5186f42b2b50168029d81e58e800b690877ef0b30580d107659250da1d1" dependencies = [ - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-program", - "spl-program-error-derive", + "spl-program-error-derive 0.4.1", "thiserror 1.0.69", ] +[[package]] +name = "spl-program-error" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdebc8b42553070b75aa5106f071fef2eb798c64a7ec63375da4b1f058688c6" +dependencies = [ + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg", + "solana-program-error", + "spl-program-error-derive 0.5.0", + "thiserror 2.0.18", +] + [[package]] name = "spl-program-error-derive" version = "0.4.1" @@ -7946,7 +7101,19 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.9", - "syn 2.0.104", + "syn 2.0.114", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2539e259c66910d78593475540e8072f0b10f0f61d7607bbf7593899ed52d0" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.114", ] [[package]] @@ -7956,7 +7123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd99ff1e9ed2ab86e3fd582850d47a739fec1be9f4661cba1782d3a0f26805f3" dependencies = [ "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-account-info", "solana-decode-error", @@ -7966,11 +7133,33 @@ dependencies = [ "solana-pubkey", "spl-discriminator", "spl-pod", - "spl-program-error", - "spl-type-length-value", + "spl-program-error 0.6.0", + "spl-type-length-value 0.7.0", "thiserror 1.0.69", ] +[[package]] +name = "spl-tlv-account-resolution" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1408e961215688715d5a1063cbdcf982de225c45f99c82b4f7d7e1dd22b998d7" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error 0.7.0", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", +] + [[package]] name = "spl-token" version = "7.0.0" @@ -7979,13 +7168,41 @@ checksum = "ed320a6c934128d4f7e54fe00e16b8aeaecf215799d060ae14f93378da6dc834" dependencies = [ "arrayref", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "num_enum", "solana-program", "thiserror 1.0.69", ] +[[package]] +name = "spl-token" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053067c6a82c705004f91dae058b11b4780407e9ccd6799dc9e7d0fab5f242da" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-sysvar", + "thiserror 2.0.18", +] + [[package]] name = "spl-token-2022" version = "6.0.0" @@ -7994,23 +7211,23 @@ checksum = "5b27f7405010ef816587c944536b0eafbcc35206ab6ba0f2ca79f1d28e488f4f" dependencies = [ "arrayref", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "num_enum", "solana-program", "solana-security-txt", "solana-zk-sdk", - "spl-elgamal-registry", + "spl-elgamal-registry 0.1.1", "spl-memo", "spl-pod", - "spl-token", - "spl-token-confidential-transfer-ciphertext-arithmetic", - "spl-token-confidential-transfer-proof-extraction", + "spl-token 7.0.0", + "spl-token-confidential-transfer-ciphertext-arithmetic 0.2.1", + "spl-token-confidential-transfer-proof-extraction 0.2.1", "spl-token-confidential-transfer-proof-generation 0.2.0", - "spl-token-group-interface", - "spl-token-metadata-interface", - "spl-transfer-hook-interface", - "spl-type-length-value", + "spl-token-group-interface 0.5.0", + "spl-token-metadata-interface 0.6.0", + "spl-transfer-hook-interface 0.9.0", + "spl-type-length-value 0.7.0", "thiserror 1.0.69", ] @@ -8022,24 +7239,98 @@ checksum = "9048b26b0df0290f929ff91317c83db28b3ef99af2b3493dd35baa146774924c" dependencies = [ "arrayref", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "num_enum", "solana-program", "solana-security-txt", "solana-zk-sdk", - "spl-elgamal-registry", + "spl-elgamal-registry 0.1.1", "spl-memo", "spl-pod", - "spl-token", - "spl-token-confidential-transfer-ciphertext-arithmetic", - "spl-token-confidential-transfer-proof-extraction", + "spl-token 7.0.0", + "spl-token-confidential-transfer-ciphertext-arithmetic 0.2.1", + "spl-token-confidential-transfer-proof-extraction 0.2.1", "spl-token-confidential-transfer-proof-generation 0.3.0", - "spl-token-group-interface", - "spl-token-metadata-interface", - "spl-transfer-hook-interface", - "spl-type-length-value", - "thiserror 2.0.12", + "spl-token-group-interface 0.5.0", + "spl-token-metadata-interface 0.6.0", + "spl-transfer-hook-interface 0.9.0", + "spl-type-length-value 0.7.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-2022" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f0dfbb079eebaee55e793e92ca5f433744f4b71ee04880bfd6beefba5973e5" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-native-token 2.3.0", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-security-txt", + "solana-system-interface", + "solana-sysvar", + "solana-zk-sdk", + "spl-elgamal-registry 0.2.0", + "spl-memo", + "spl-pod", + "spl-token 8.0.0", + "spl-token-confidential-transfer-ciphertext-arithmetic 0.3.1", + "spl-token-confidential-transfer-proof-extraction 0.3.0", + "spl-token-confidential-transfer-proof-generation 0.4.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "spl-transfer-hook-interface 0.10.0", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-2022-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d7ae2ee6b856f8ddcbdc3b3a9f4d2141582bbe150f93e5298ee97e0251fa04" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "spl-token-confidential-transfer-proof-extraction 0.4.1", + "spl-token-confidential-transfer-proof-generation 0.4.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", ] [[package]] @@ -8054,6 +7345,18 @@ dependencies = [ "solana-zk-sdk", ] +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cddd52bfc0f1c677b41493dafa3f2dbbb4b47cf0990f08905429e19dc8289b35" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519", + "solana-zk-sdk", +] + [[package]] name = "spl-token-confidential-transfer-proof-extraction" version = "0.2.1" @@ -8065,7 +7368,47 @@ dependencies = [ "solana-program", "solana-zk-sdk", "spl-pod", - "thiserror 2.0.12", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe2629860ff04c17bafa9ba4bed8850a404ecac81074113e1f840dbd0ebb7bd6" +dependencies = [ + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512c85bdbbb4cbcc2038849a9e164c958b16541f252b53ea1a3933191c0a4a1a" +dependencies = [ + "bytemuck", + "solana-account-info", + "solana-curve25519", + "solana-instruction", + "solana-instructions-sysvar", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "solana-sdk-ids", + "solana-zk-sdk", + "spl-pod", + "thiserror 2.0.18", ] [[package]] @@ -8087,7 +7430,18 @@ checksum = "0e3597628b0d2fe94e7900fd17cdb4cfbb31ee35c66f82809d27d86e44b2848b" dependencies = [ "curve25519-dalek 4.1.3", "solana-zk-sdk", - "thiserror 2.0.12", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk", + "thiserror 2.0.18", ] [[package]] @@ -8097,7 +7451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d595667ed72dbfed8c251708f406d7c2814a3fa6879893b323d56a10bedfc799" dependencies = [ "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-decode-error", "solana-instruction", @@ -8109,14 +7463,33 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "spl-token-group-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "thiserror 2.0.18", +] + [[package]] name = "spl-token-metadata-interface" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" dependencies = [ - "borsh 1.5.7", - "num-derive 0.4.2", + "borsh 1.6.0", + "num-derive", "num-traits", "solana-borsh", "solana-decode-error", @@ -8126,43 +7499,107 @@ dependencies = [ "solana-pubkey", "spl-discriminator", "spl-pod", - "spl-type-length-value", + "spl-type-length-value 0.7.0", "thiserror 1.0.69", ] +[[package]] +name = "spl-token-metadata-interface" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" +dependencies = [ + "borsh 1.6.0", + "num-derive", + "num-traits", + "solana-borsh", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", +] + [[package]] name = "spl-transfer-hook-interface" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error 0.6.0", + "spl-tlv-account-resolution 0.9.0", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7e905b849b6aba63bde8c4badac944ebb6c8e6e14817029cbe1bc16829133bd" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info", + "solana-cpi", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey", + "spl-discriminator", + "spl-pod", + "spl-program-error 0.7.0", + "spl-tlv-account-resolution 0.10.0", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-type-length-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" dependencies = [ - "arrayref", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-account-info", - "solana-cpi", "solana-decode-error", - "solana-instruction", "solana-msg", "solana-program-error", - "solana-pubkey", "spl-discriminator", "spl-pod", - "spl-program-error", - "spl-tlv-account-resolution", - "spl-type-length-value", "thiserror 1.0.69", ] [[package]] name = "spl-type-length-value" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" dependencies = [ "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-account-info", "solana-decode-error", @@ -8170,14 +7607,14 @@ dependencies = [ "solana-program-error", "spl-discriminator", "spl-pod", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -8210,9 +7647,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -8234,18 +7671,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.2" @@ -8254,7 +7679,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -8264,7 +7689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "system-configuration-sys 0.5.0", ] @@ -8274,8 +7699,8 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.9.4", + "bitflags 2.10.0", + "core-foundation", "system-configuration-sys 0.6.0", ] @@ -8299,6 +7724,30 @@ dependencies = [ "libc", ] +[[package]] +name = "tabled" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e39a2ee1fbcd360805a771e1b300f78cc88fec7b8d3e2f71cd37bbf23e725c7d" +dependencies = [ + "papergrid", + "tabled_derive", + "testing_table", +] + +[[package]] +name = "tabled_derive" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea5d1b13ca6cff1f9231ffd62f15eefd72543dab5e468735f1a456728a02846" +dependencies = [ + "heck 0.5.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "tap" version = "1.0.1" @@ -8340,26 +7789,17 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "task-local-extensions" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba323866e5d033818e3240feeb9f7db2c4296674e4d9e16b97b7bf8f490434e8" -dependencies = [ - "pin-utils", -] - [[package]] name = "tempfile" -version = "3.20.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -8371,6 +7811,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "testing_table" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014cc" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -8382,11 +7831,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.18", ] [[package]] @@ -8397,18 +7846,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -8422,30 +7871,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" dependencies = [ "num-conv", "time-core", @@ -8453,9 +7902,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -8463,9 +7912,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -8478,33 +7927,30 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43864ed400b6043a4757a25c7a64a8efde741aed79a056a2fb348a406701bb35" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -8529,11 +7975,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.29", + "rustls 0.23.36", "tokio", ] @@ -8553,32 +7999,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -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 0.21.12", - "tokio", - "tokio-rustls 0.24.1", - "tungstenite", - "webpki-roots 0.25.4", -] - [[package]] name = "tokio-util" version = "0.6.10" @@ -8596,9 +8016,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.15" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -8624,8 +8044,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -8637,20 +8057,50 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.13.0", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow", ] +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -8659,9 +8109,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -8674,17 +8124,22 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ - "bitflags 2.9.1", + "async-compression", + "bitflags 2.10.0", "bytes", + "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", + "http-body-util", "iri-string", "pin-project-lite", + "tokio", + "tokio-util 0.7.18", "tower", "tower-layer", "tower-service", @@ -8704,9 +8159,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -8716,20 +8171,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -8750,9 +8205,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "sharded-slab", "thread_local", @@ -8765,32 +8220,11 @@ 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 0.2.12", - "httparse", - "log", - "rand 0.8.5", - "rustls 0.21.12", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", - "webpki-roots 0.24.0", -] - [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uint" @@ -8812,15 +8246,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" @@ -8830,15 +8264,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" - -[[package]] -name = "unicode-xid" -version = "0.2.6" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "universal-hash" @@ -8877,42 +8305,31 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - [[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - [[package]] name = "uuid" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", - "serde", + "serde_core", "wasm-bindgen", ] @@ -8949,16 +8366,6 @@ dependencies = [ "libc", ] -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -8981,47 +8388,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.104", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -9030,9 +8425,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -9040,31 +8435,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.104", - "wasm-bindgen-backend", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -9080,33 +8475,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-root-certs" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" -dependencies = [ - "webpki-root-certs 1.0.2", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webpki-roots" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" -dependencies = [ - "rustls-webpki 0.101.7", -] - [[package]] name = "webpki-roots" version = "0.25.4" @@ -9114,13 +8482,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] -name = "wide" -version = "0.7.33" +name = "webpki-roots" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ - "bytemuck", - "safe_arch", + "rustls-pki-types", ] [[package]] @@ -9141,11 +8508,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -9156,9 +8523,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", @@ -9169,37 +8536,37 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.5.3" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ "windows-link", "windows-result", @@ -9208,31 +8575,22 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -9266,22 +8624,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-link", ] [[package]] @@ -9317,27 +8669,21 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -9352,15 +8698,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -9376,15 +8716,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -9400,9 +8734,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -9412,15 +8746,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -9436,15 +8764,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -9460,15 +8782,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -9484,15 +8800,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -9508,15 +8818,15 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -9532,19 +8842,16 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wyz" @@ -9555,31 +8862,12 @@ dependencies = [ "tap", ] -[[package]] -name = "x509-parser" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" -dependencies = [ - "asn1-rs", - "base64 0.13.1", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] - [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -9587,34 +8875,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn 2.0.114", + "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] @@ -9634,35 +8922,35 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn 2.0.114", + "synstructure", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -9671,9 +8959,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -9682,15 +8970,21 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.114", ] +[[package]] +name = "zmij" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" + [[package]] name = "zstd" version = "0.13.3" @@ -9711,9 +9005,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 29273e1..1a290f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] resolver = "2" -members = ["programs/*", "client"] +members = ["programs/*"] -# Force newer proc-macro2 version compatible with Rust 1.87 [workspace.dependencies] proc-macro2 = "1.0.95" +blake3 = "=1.8.2" [profile.release] overflow-checks = true @@ -13,4 +13,4 @@ codegen-units = 1 [profile.release.build-override] opt-level = 3 incremental = false -codegen-units = 1 \ No newline at end of file +codegen-units = 1 diff --git a/README.md b/README.md index 49f044c..47dfa9a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,20 @@ -# raydium-cp-swap +# Rentfree AMM example -A revamped constant product AMM program optimized for straightforward pool deployment along with additional features and integrations: -- No Openbook market ID is required for pool creation -- Token22 is supported -- Built-in price oracle -- Optimized in Anchor +Fork of Raydium AMM that creates markets without paying rent-exemption. -The program has been audited by [MadShield](https://www.madshield.xyz/). The report can be found [here](https://github.com/raydium-io/raydium-docs/tree/master/audit/MadShield%20Q1%202024). +- drop-in SDK, minimal code diff +- no extra CU overhead on hot paths +- no UX diff on hot paths -The program assets are in-scope for Raydium’s [Immunefi bug bounty program](https://immunefi.com/bug-bounty/raydium/). +The SDK sponsors rent-exemption on behalf of your users for: +- PoolState +- Token Vaults +- LP Mint account +- User ATAs + +Upgrading your program accounts to be rent-free is fast and straightforward because Light-token is a superset of SPL-token. See [here](https://www.zkcompression.com/light-token/defi/programs) for a guide. + +For hands-on support, join the [Developer Discord](https://discord.com/invite/7cJ8BhAXhu). ## Environment Setup @@ -30,20 +36,35 @@ The program assets are in-scope for Raydium’s [Immunefi bug bounty program](ht 3. install `Anchor` ```shell - # Installing using Anchor version manager (avm) + # Installing using Anchor version manager (avm) cargo install --git https://github.com/coral-xyz/anchor avm --locked --force # Install anchor - avm install 0.31.0 + avm install 0.31.1 ``` ## Quickstart -Clone the repository and test the program. +1. install the latest compression dependencies + +```shell +npm i -g @lightprotocol/zk-compression-cli@alpha --force + +cargo install --git https://github.com/lightprotocol/photon.git --rev 6ba6813 --locked --force +``` + +2. Clone the repository and install node dependencies ```shell -git clone https://github.com/raydium-io/raydium-cp-swap -cd raydium-cp-swap && yarn && anchor test +git clone https://github.com/Lightprotocol/cp-swap-reference + +cd raydium-cp-swap && yarn +``` + +3. Run the tests + +```shell +yarn test ``` ## License diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 0d46f87..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,82 +0,0 @@ -# Raydium CP-Swap (CPMM) Bug Bounty Program - -Raydium's full bug bounty program with ImmuneFi can be found at: https://immunefi.com/bounty/raydium/ - -## Rewards by Threat Level - -Rewards are distributed according to the impact of the vulnerability based on the Immunefi Vulnerability Severity Classification System V2.3. This is a simplified 5-level scale, focusing on the impact of the vulnerability reported. - -### Smart Contracts - -| Severity | Bounty | -| -------- | ------------------------- | -| Critical | USD 50,000 to USD 505,000 | -| High | USD 40,000 | -| Medium | USD 5,000 | - -All bug reports must include a Proof of Concept (PoC) demonstrating how the vulnerability can be exploited to impact an asset-in-scope to be eligible for a reward. Critical and High severity bug reports should also include a suggestion for a fix. Explanations and statements are not accepted as PoC and code is required. - -Rewards for critical smart contract bug reports will be further capped at 10% of direct funds at risk if the bug discovered is exploited. However, there is a minimum reward of USD 50,000. - -Bugs in `raydium-sdk` and other code outside of the smart contract will be assessed on a case-by-case basis. - -## Report Submission - -Please email security@reactorlabs.io with a detailed description of the attack vector. For high- and critical-severity reports, please include a proof of concept. We will reach back out within 24 hours with additional questions or next steps on the bug bounty. - -## Payout Information - -Payouts are handled by the Raydium team directly and are denominated in USD. Payouts can be done in RAY, SOL, or USDC. - -## Out of Scope & Rules - -The following vulnerabilities are excluded from the rewards for this bug bounty program: - -- Attacks that the reporter has already exploited themselves, leading to damage -- Attacks requiring access to leaked keys/credentials -- Attacks requiring access to privileged addresses (governance, strategist) -- Incorrect data supplied by third party oracles (not excluding oracle manipulation/flash loan attacks) -- Basic economic governance attacks (e.g. 51% attack) -- Lack of liquidity -- Best practice critiques -- Sybil attacks -- Centralization risks -- Any UI bugs -- Bugs in the core Solana runtime (please submit these to [Solana's bug bounty program](https://github.com/solana-labs/solana/security/policy)) -- Vulnerabilities that require a validator to execute them -- Vulnerabilities requiring access to privileged keys/credentials -- MEV vectors the team is already aware of - -## AMM Assets in Scope - -| Target | Type | -| ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/lib.rs | Smart Contract - lib | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/error.rs | Smart Contract - error | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/collect_fund_fee.rs | Smart Contract - collect_fund_fee | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/collect_protocol_fee.rs | Smart Contract - collect_protocol_fee | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/create_config.rs | Smart Contract - create_config | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/mod.rs | Smart Contract - admin mod | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/update_config.rs | Smart Contract - update_config | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/admin/update_pool_status.rs | Smart Contract - update_pool_status | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/deposit.rs | Smart Contract - deposit | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/initialize.rs | Smart Contract - initialize | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/mod.rs | Smart Contract - instructions mod | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/swap_base_input.rs | Smart Contract - swap_base_input | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/swap_base_output.rs | Smart Contract - swap_base_output | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/instructions/withdraw.rs | Smart Contract - withdraw | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/states/config.rs | Smart Contract - config | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/states/events.rs | Smart Contract - events | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/states/mod.rs | Smart Contract - states mod | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/states/pool.rs | Smart Contract - pool | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/utils/math.rs | Smart Contract - math | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/utils/mod.rs | Smart Contract - utils mod | -| https://github.com/raydium-io/raydium-cp-swap/blob/master/programs/cp-swap/src/utils/token.rs | Smart Contract - utils token | - -## Additional Information - -A public testnet of Raydium's CPMM can be found at A public testnet of Raydium’s AMM can be found at https://explorer.solana.com/address/CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW?cluster=devnet - -A public testnet of OpenBook's Central Limit Order Book can be found at https://explorer.solana.com/address/EoTcMgcDRTJVZDMZWBoU6rhYHZfkNTVEAfz3uUJRcYGj - -If a Critical Impact can be caused to any other asset managed by Raydium that isn't on this table but for which the impact is in the Impacts in Scope section below, you are encouraged to submit it for consideration by the project. This only applies to Critical impacts. diff --git a/client/Cargo.toml b/client/Cargo.toml deleted file mode 100644 index 074c134..0000000 --- a/client/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "client" -version = "0.1.0" -edition = "2021" - -[features] -devnet = ["raydium-cp-swap/devnet"] - -[dependencies] -anchor-client = { version = "=0.31.1" } -anchor-lang = { version = "=0.31.1" } -anchor-spl = { version = "=0.31.1", features = ["idl-build"] } -raydium-cp-swap = { path = "../programs/cp-swap", features = [ - "no-entrypoint", - "client", -] } -solana-sdk = "2.2" -solana-client = "2.2" -solana-account-decoder = "2.2" -solana-transaction-status = "2.2" -clap = { version = "4.1.8", features = ["derive"] } -anyhow = "1.0.32" -rand = "0.9.0" -hex = "0.4.3" -configparser = "3.0.0" -serde_json = { version = "1.0.78" } -serde = { version = "1.0", features = ["derive"] } -arrayref = "0.3.7" -bs58 = { version = "0.5.0" } -bincode = { version = "1.3.3" } -regex = "1" -colorful = "0.3.2" -base64 = "0.21.0" -bytemuck = { version = "1.23.0", features = ["derive"] } diff --git a/client/src/instructions/amm_instructions.rs b/client/src/instructions/amm_instructions.rs deleted file mode 100644 index 2f15ec9..0000000 --- a/client/src/instructions/amm_instructions.rs +++ /dev/null @@ -1,332 +0,0 @@ -use anchor_client::{Client, Cluster}; -use anchor_spl::{ - associated_token::spl_associated_token_account, memo::spl_memo, token::spl_token, - token_2022::spl_token_2022, -}; -use anyhow::Result; -use solana_sdk::{instruction::Instruction, pubkey::Pubkey, system_program, sysvar}; - -use raydium_cp_swap::accounts as raydium_cp_accounts; -use raydium_cp_swap::instruction as raydium_cp_instructions; -use raydium_cp_swap::{ - states::{AMM_CONFIG_SEED, OBSERVATION_SEED, POOL_LP_MINT_SEED, POOL_SEED, POOL_VAULT_SEED}, - AUTH_SEED, -}; -use std::rc::Rc; - -use super::super::{read_keypair_file, ClientConfig}; - -pub fn initialize_pool_instr( - config: &ClientConfig, - token_0_mint: Pubkey, - token_1_mint: Pubkey, - token_0_program: Pubkey, - token_1_program: Pubkey, - user_token_0_account: Pubkey, - user_token_1_account: Pubkey, - create_pool_fee: Pubkey, - random_pool_id: Option, - init_amount_0: u64, - init_amount_1: u64, - open_time: u64, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(config.raydium_cp_program)?; - - let amm_config_index = 0u16; - let (amm_config_key, __bump) = Pubkey::find_program_address( - &[AMM_CONFIG_SEED.as_bytes(), &amm_config_index.to_be_bytes()], - &program.id(), - ); - - let pool_account_key = if random_pool_id.is_some() { - random_pool_id.unwrap() - } else { - Pubkey::find_program_address( - &[ - POOL_SEED.as_bytes(), - amm_config_key.to_bytes().as_ref(), - token_0_mint.to_bytes().as_ref(), - token_1_mint.to_bytes().as_ref(), - ], - &program.id(), - ) - .0 - }; - - let (authority, __bump) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &program.id()); - let (token_0_vault, __bump) = Pubkey::find_program_address( - &[ - POOL_VAULT_SEED.as_bytes(), - pool_account_key.to_bytes().as_ref(), - token_0_mint.to_bytes().as_ref(), - ], - &program.id(), - ); - let (token_1_vault, __bump) = Pubkey::find_program_address( - &[ - POOL_VAULT_SEED.as_bytes(), - pool_account_key.to_bytes().as_ref(), - token_1_mint.to_bytes().as_ref(), - ], - &program.id(), - ); - let (lp_mint_key, __bump) = Pubkey::find_program_address( - &[ - POOL_LP_MINT_SEED.as_bytes(), - pool_account_key.to_bytes().as_ref(), - ], - &program.id(), - ); - let (observation_key, __bump) = Pubkey::find_program_address( - &[ - OBSERVATION_SEED.as_bytes(), - pool_account_key.to_bytes().as_ref(), - ], - &program.id(), - ); - - let mut instructions = program - .request() - .accounts(raydium_cp_accounts::Initialize { - creator: program.payer(), - amm_config: amm_config_key, - authority, - pool_state: pool_account_key, - token_0_mint, - token_1_mint, - lp_mint: lp_mint_key, - creator_token_0: user_token_0_account, - creator_token_1: user_token_1_account, - creator_lp_token: spl_associated_token_account::get_associated_token_address( - &program.payer(), - &lp_mint_key, - ), - token_0_vault, - token_1_vault, - create_pool_fee, - observation_state: observation_key, - token_program: spl_token::id(), - token_0_program, - token_1_program, - associated_token_program: spl_associated_token_account::id(), - system_program: system_program::id(), - rent: sysvar::rent::id(), - }) - .args(raydium_cp_instructions::Initialize { - init_amount_0, - init_amount_1, - open_time, - }) - .instructions()?; - if random_pool_id.is_some() { - // update account signer as true for random pool - for account in instructions[0].accounts.iter_mut() { - if account.pubkey == random_pool_id.unwrap() { - account.is_signer = true; - break; - } - } - } - Ok(instructions) -} - -pub fn deposit_instr( - config: &ClientConfig, - pool_id: Pubkey, - token_0_mint: Pubkey, - token_1_mint: Pubkey, - token_lp_mint: Pubkey, - token_0_vault: Pubkey, - token_1_vault: Pubkey, - user_token_0_account: Pubkey, - user_token_1_account: Pubkey, - user_token_lp_account: Pubkey, - lp_token_amount: u64, - maximum_token_0_amount: u64, - maximum_token_1_amount: u64, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(config.raydium_cp_program)?; - - let (authority, __bump) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &program.id()); - - let instructions = program - .request() - .accounts(raydium_cp_accounts::Deposit { - owner: program.payer(), - authority, - pool_state: pool_id, - owner_lp_token: user_token_lp_account, - token_0_account: user_token_0_account, - token_1_account: user_token_1_account, - token_0_vault, - token_1_vault, - token_program: spl_token::id(), - token_program_2022: spl_token_2022::id(), - vault_0_mint: token_0_mint, - vault_1_mint: token_1_mint, - lp_mint: token_lp_mint, - }) - .args(raydium_cp_instructions::Deposit { - lp_token_amount, - maximum_token_0_amount, - maximum_token_1_amount, - }) - .instructions()?; - Ok(instructions) -} - -pub fn withdraw_instr( - config: &ClientConfig, - pool_id: Pubkey, - token_0_mint: Pubkey, - token_1_mint: Pubkey, - token_lp_mint: Pubkey, - token_0_vault: Pubkey, - token_1_vault: Pubkey, - user_token_0_account: Pubkey, - user_token_1_account: Pubkey, - user_token_lp_account: Pubkey, - lp_token_amount: u64, - minimum_token_0_amount: u64, - minimum_token_1_amount: u64, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(config.raydium_cp_program)?; - - let (authority, __bump) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &program.id()); - - let instructions = program - .request() - .accounts(raydium_cp_accounts::Withdraw { - owner: program.payer(), - authority, - pool_state: pool_id, - owner_lp_token: user_token_lp_account, - token_0_account: user_token_0_account, - token_1_account: user_token_1_account, - token_0_vault, - token_1_vault, - token_program: spl_token::id(), - token_program_2022: spl_token_2022::id(), - vault_0_mint: token_0_mint, - vault_1_mint: token_1_mint, - lp_mint: token_lp_mint, - memo_program: spl_memo::id(), - }) - .args(raydium_cp_instructions::Withdraw { - lp_token_amount, - minimum_token_0_amount, - minimum_token_1_amount, - }) - .instructions()?; - Ok(instructions) -} - -pub fn swap_base_input_instr( - config: &ClientConfig, - pool_id: Pubkey, - amm_config: Pubkey, - observation_account: Pubkey, - input_token_account: Pubkey, - output_token_account: Pubkey, - input_vault: Pubkey, - output_vault: Pubkey, - input_token_mint: Pubkey, - output_token_mint: Pubkey, - input_token_program: Pubkey, - output_token_program: Pubkey, - amount_in: u64, - minimum_amount_out: u64, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(config.raydium_cp_program)?; - - let (authority, __bump) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &program.id()); - - let instructions = program - .request() - .accounts(raydium_cp_accounts::Swap { - payer: program.payer(), - authority, - amm_config, - pool_state: pool_id, - input_token_account, - output_token_account, - input_vault, - output_vault, - input_token_program, - output_token_program, - input_token_mint, - output_token_mint, - observation_state: observation_account, - }) - .args(raydium_cp_instructions::SwapBaseInput { - amount_in, - minimum_amount_out, - }) - .instructions()?; - Ok(instructions) -} - -pub fn swap_base_output_instr( - config: &ClientConfig, - pool_id: Pubkey, - amm_config: Pubkey, - observation_account: Pubkey, - input_token_account: Pubkey, - output_token_account: Pubkey, - input_vault: Pubkey, - output_vault: Pubkey, - input_token_mint: Pubkey, - output_token_mint: Pubkey, - input_token_program: Pubkey, - output_token_program: Pubkey, - max_amount_in: u64, - amount_out: u64, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(config.raydium_cp_program)?; - - let (authority, __bump) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &program.id()); - - let instructions = program - .request() - .accounts(raydium_cp_accounts::Swap { - payer: program.payer(), - authority, - amm_config, - pool_state: pool_id, - input_token_account, - output_token_account, - input_vault, - output_vault, - input_token_program, - output_token_program, - input_token_mint, - output_token_mint, - observation_state: observation_account, - }) - .args(raydium_cp_instructions::SwapBaseOutput { - max_amount_in, - amount_out, - }) - .instructions()?; - Ok(instructions) -} diff --git a/client/src/instructions/events_instructions_parse.rs b/client/src/instructions/events_instructions_parse.rs deleted file mode 100644 index b04103a..0000000 --- a/client/src/instructions/events_instructions_parse.rs +++ /dev/null @@ -1,507 +0,0 @@ -use anchor_client::ClientError; -use anchor_lang::Discriminator; -use anyhow::Result; -use colorful::Color; -use colorful::Colorful; -use raydium_cp_swap::instruction; -use raydium_cp_swap::states::*; -use regex::Regex; -use solana_transaction_status::{ - option_serializer::OptionSerializer, EncodedTransaction, UiTransactionStatusMeta, -}; - -const PROGRAM_LOG: &str = "Program log: "; -const PROGRAM_DATA: &str = "Program data: "; -const DISCRIMINATOR_LEN: usize = 8; -pub enum InstructionDecodeType { - BaseHex, - Base64, - Base58, -} - -pub fn parse_program_event( - self_program_str: &str, - meta: Option, -) -> Result<(), ClientError> { - let logs: Vec = if let Some(meta_data) = meta { - let log_messages = if let OptionSerializer::Some(log_messages) = meta_data.log_messages { - log_messages - } else { - Vec::new() - }; - log_messages - } else { - Vec::new() - }; - let mut logs = &logs[..]; - if !logs.is_empty() { - if let Ok(mut execution) = Execution::new(&mut logs) { - for l in logs { - let (new_program, did_pop) = - if !execution.is_empty() && self_program_str == execution.program() { - handle_program_log(self_program_str, &l, true).unwrap_or_else(|e| { - println!("Unable to parse log: {e}"); - std::process::exit(1); - }) - } else { - let (program, did_pop) = handle_system_log(self_program_str, l); - (program, did_pop) - }; - // Switch program context on CPI. - if let Some(new_program) = new_program { - execution.push(new_program); - } - // Program returned. - if did_pop { - execution.pop(); - } - } - } - } else { - println!("log is empty"); - } - Ok(()) -} - -struct Execution { - stack: Vec, -} - -impl Execution { - pub fn new(logs: &mut &[String]) -> Result { - let l = &logs[0]; - *logs = &logs[1..]; - - let re = Regex::new(r"^Program (.*) invoke.*$").unwrap(); - let c = re - .captures(l) - .ok_or_else(|| ClientError::LogParseError(l.to_string()))?; - let program = c - .get(1) - .ok_or_else(|| ClientError::LogParseError(l.to_string()))? - .as_str() - .to_string(); - Ok(Self { - stack: vec![program], - }) - } - - pub fn program(&self) -> String { - assert!(!self.stack.is_empty()); - self.stack[self.stack.len() - 1].clone() - } - - pub fn is_empty(&self) -> bool { - self.stack.is_empty() - } - - pub fn push(&mut self, new_program: String) { - self.stack.push(new_program); - } - - pub fn pop(&mut self) { - assert!(!self.stack.is_empty()); - self.stack.pop().unwrap(); - } -} - -pub fn handle_program_log( - self_program_str: &str, - l: &str, - with_prefix: bool, -) -> Result<(Option, bool), ClientError> { - // Log emitted from the current program. - if let Some(log) = if with_prefix { - l.strip_prefix(PROGRAM_LOG) - .or_else(|| l.strip_prefix(PROGRAM_DATA)) - } else { - Some(l) - } { - if l.starts_with(&format!("Program log:")) { - // not log event - return Ok((None, false)); - } - let borsh_bytes = - match base64::Engine::decode(&base64::engine::general_purpose::STANDARD, log) { - Ok(borsh_bytes) => borsh_bytes, - _ => { - println!("Could not base64 decode log: {}", log); - return Ok((None, false)); - } - }; - - if borsh_bytes.len() < DISCRIMINATOR_LEN { - return Err(ClientError::LogParseError( - format!("log data is too short: {}", log).to_string(), - )); - } - let disc = &borsh_bytes[..DISCRIMINATOR_LEN]; - let mut slice: &[u8] = &borsh_bytes[DISCRIMINATOR_LEN..]; - - match disc { - SwapEvent::DISCRIMINATOR => { - println!("{:#?}", decode_event::(&mut slice)?); - } - LpChangeEvent::DISCRIMINATOR => { - println!("{:#?}", decode_event::(&mut slice)?); - } - _ => { - println!("unknow event: {}", l); - } - } - return Ok((None, false)); - } else { - let (program, did_pop) = handle_system_log(self_program_str, l); - return Ok((program, did_pop)); - } -} - -fn handle_system_log(this_program_str: &str, log: &str) -> (Option, bool) { - if log.starts_with(&format!("Program {this_program_str} invoke")) { - (Some(this_program_str.to_string()), false) - } else if log.contains("invoke") { - (Some("cpi".to_string()), false) // Any string will do. - } else { - let re = Regex::new(r"^Program (.*) success*$").unwrap(); - if re.is_match(log) { - (None, true) - } else { - (None, false) - } - } -} - -fn decode_event( - slice: &mut &[u8], -) -> Result { - let event: T = anchor_lang::AnchorDeserialize::deserialize(slice) - .map_err(|e| ClientError::LogParseError(e.to_string()))?; - Ok(event) -} - -pub fn parse_program_instruction( - self_program_str: &str, - encoded_transaction: EncodedTransaction, - meta: Option, -) -> Result<(), ClientError> { - let ui_raw_msg = match encoded_transaction { - solana_transaction_status::EncodedTransaction::Json(ui_tx) => { - let ui_message = ui_tx.message; - // println!("{:#?}", ui_message); - match ui_message { - solana_transaction_status::UiMessage::Raw(ui_raw_msg) => ui_raw_msg, - _ => solana_transaction_status::UiRawMessage { - header: solana_sdk::message::MessageHeader::default(), - account_keys: Vec::new(), - recent_blockhash: "".to_string(), - instructions: Vec::new(), - address_table_lookups: None, - }, - } - } - _ => solana_transaction_status::UiRawMessage { - header: solana_sdk::message::MessageHeader::default(), - account_keys: Vec::new(), - recent_blockhash: "".to_string(), - instructions: Vec::new(), - address_table_lookups: None, - }, - }; - // append lookup table keys if necessary - if meta.is_some() { - let mut account_keys = ui_raw_msg.account_keys; - let meta = meta.clone().unwrap(); - match meta.loaded_addresses { - OptionSerializer::Some(addresses) => { - let mut writeable_address = addresses.writable; - let mut readonly_address = addresses.readonly; - account_keys.append(&mut writeable_address); - account_keys.append(&mut readonly_address); - } - _ => {} - } - let program_index = account_keys - .iter() - .position(|r| r == self_program_str) - .unwrap(); - // println!("{}", program_index); - // println!("{:#?}", account_keys); - for (i, ui_compiled_instruction) in ui_raw_msg.instructions.iter().enumerate() { - if (ui_compiled_instruction.program_id_index as usize) == program_index { - let out_put = format!("instruction #{}", i + 1); - println!("{}", out_put.gradient(Color::Green)); - handle_program_instruction( - &ui_compiled_instruction.data, - InstructionDecodeType::Base58, - )?; - } - } - - match meta.inner_instructions { - OptionSerializer::Some(inner_instructions) => { - for inner in inner_instructions { - for (i, instruction) in inner.instructions.iter().enumerate() { - match instruction { - solana_transaction_status::UiInstruction::Compiled( - ui_compiled_instruction, - ) => { - if (ui_compiled_instruction.program_id_index as usize) - == program_index - { - let out_put = - format!("inner_instruction #{}.{}", inner.index + 1, i + 1); - println!("{}", out_put.gradient(Color::Green)); - handle_program_instruction( - &ui_compiled_instruction.data, - InstructionDecodeType::Base58, - )?; - } - } - _ => {} - } - } - } - } - _ => {} - } - } - Ok(()) -} - -pub fn handle_program_instruction( - instr_data: &str, - decode_type: InstructionDecodeType, -) -> Result<(), ClientError> { - let data; - match decode_type { - InstructionDecodeType::BaseHex => { - data = hex::decode(instr_data).unwrap(); - } - InstructionDecodeType::Base64 => { - let borsh_bytes = match base64::Engine::decode( - &base64::engine::general_purpose::STANDARD, - instr_data, - ) { - Ok(borsh_bytes) => borsh_bytes, - _ => { - println!("Could not base64 decode instruction: {}", instr_data); - return Ok(()); - } - }; - data = borsh_bytes; - } - InstructionDecodeType::Base58 => { - let borsh_bytes = match bs58::decode(instr_data).into_vec() { - Ok(borsh_bytes) => borsh_bytes, - _ => { - println!("Could not base58 decode instruction: {}", instr_data); - return Ok(()); - } - }; - data = borsh_bytes; - } - } - - if data.len() < DISCRIMINATOR_LEN { - return Err(ClientError::LogParseError( - format!("instruction data is too short: {}", instr_data).to_string(), - )); - } - let disc = &data[..DISCRIMINATOR_LEN]; - let mut ix_data: &[u8] = &data[DISCRIMINATOR_LEN..]; - - match disc { - instruction::CreateAmmConfig::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct CreateAmmConfig { - pub index: u16, - pub trade_fee_rate: u64, - pub protocol_fee_rate: u64, - pub fund_fee_rate: u64, - pub create_pool_fee: u64, - } - impl From for CreateAmmConfig { - fn from(instr: instruction::CreateAmmConfig) -> CreateAmmConfig { - CreateAmmConfig { - index: instr.index, - trade_fee_rate: instr.trade_fee_rate, - protocol_fee_rate: instr.protocol_fee_rate, - fund_fee_rate: instr.fund_fee_rate, - create_pool_fee: instr.create_pool_fee, - } - } - } - println!("{:#?}", CreateAmmConfig::from(ix)); - } - instruction::UpdateAmmConfig::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct UpdateAmmConfig { - pub param: u8, - pub value: u64, - } - impl From for UpdateAmmConfig { - fn from(instr: instruction::UpdateAmmConfig) -> UpdateAmmConfig { - UpdateAmmConfig { - param: instr.param, - value: instr.value, - } - } - } - println!("{:#?}", UpdateAmmConfig::from(ix)); - } - instruction::Initialize::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct Initialize { - pub init_amount_0: u64, - pub init_amount_1: u64, - pub open_time: u64, - } - impl From for Initialize { - fn from(instr: instruction::Initialize) -> Initialize { - Initialize { - init_amount_0: instr.init_amount_0, - init_amount_1: instr.init_amount_1, - open_time: instr.open_time, - } - } - } - println!("{:#?}", Initialize::from(ix)); - } - instruction::UpdatePoolStatus::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct UpdatePoolStatus { - pub status: u8, - } - impl From for UpdatePoolStatus { - fn from(instr: instruction::UpdatePoolStatus) -> UpdatePoolStatus { - UpdatePoolStatus { - status: instr.status, - } - } - } - println!("{:#?}", UpdatePoolStatus::from(ix)); - } - instruction::CollectProtocolFee::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct CollectProtocolFee { - pub amount_0_requested: u64, - pub amount_1_requested: u64, - } - impl From for CollectProtocolFee { - fn from(instr: instruction::CollectProtocolFee) -> CollectProtocolFee { - CollectProtocolFee { - amount_0_requested: instr.amount_0_requested, - amount_1_requested: instr.amount_1_requested, - } - } - } - println!("{:#?}", CollectProtocolFee::from(ix)); - } - instruction::CollectFundFee::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct CollectFundFee { - pub amount_0_requested: u64, - pub amount_1_requested: u64, - } - impl From for CollectFundFee { - fn from(instr: instruction::CollectFundFee) -> CollectFundFee { - CollectFundFee { - amount_0_requested: instr.amount_0_requested, - amount_1_requested: instr.amount_1_requested, - } - } - } - println!("{:#?}", CollectFundFee::from(ix)); - } - instruction::Deposit::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct Deposit { - pub lp_token_amount: u64, - pub maximum_token_0_amount: u64, - pub maximum_token_1_amount: u64, - } - impl From for Deposit { - fn from(instr: instruction::Deposit) -> Deposit { - Deposit { - lp_token_amount: instr.lp_token_amount, - maximum_token_0_amount: instr.maximum_token_0_amount, - maximum_token_1_amount: instr.maximum_token_1_amount, - } - } - } - println!("{:#?}", Deposit::from(ix)); - } - instruction::Withdraw::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct Withdraw { - pub lp_token_amount: u64, - pub minimum_token_0_amount: u64, - pub minimum_token_1_amount: u64, - } - impl From for Withdraw { - fn from(instr: instruction::Withdraw) -> Withdraw { - Withdraw { - lp_token_amount: instr.lp_token_amount, - minimum_token_0_amount: instr.minimum_token_0_amount, - minimum_token_1_amount: instr.minimum_token_1_amount, - } - } - } - println!("{:#?}", Withdraw::from(ix)); - } - instruction::SwapBaseInput::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct SwapBaseInput { - pub amount_in: u64, - pub minimum_amount_out: u64, - } - impl From for SwapBaseInput { - fn from(instr: instruction::SwapBaseInput) -> SwapBaseInput { - SwapBaseInput { - amount_in: instr.amount_in, - minimum_amount_out: instr.minimum_amount_out, - } - } - } - println!("{:#?}", SwapBaseInput::from(ix)); - } - instruction::SwapBaseOutput::DISCRIMINATOR => { - let ix = decode_instruction::(&mut ix_data).unwrap(); - #[derive(Debug)] - pub struct SwapBaseOutput { - pub max_amount_in: u64, - pub amount_out: u64, - } - impl From for SwapBaseOutput { - fn from(instr: instruction::SwapBaseOutput) -> SwapBaseOutput { - SwapBaseOutput { - max_amount_in: instr.max_amount_in, - amount_out: instr.amount_out, - } - } - } - println!("{:#?}", SwapBaseOutput::from(ix)); - } - _ => { - println!("unknow instruction: {}", instr_data); - } - } - Ok(()) -} - -fn decode_instruction( - slice: &mut &[u8], -) -> Result { - let instruction: T = anchor_lang::AnchorDeserialize::deserialize(slice) - .map_err(|_| anchor_lang::error::ErrorCode::InstructionDidNotDeserialize)?; - Ok(instruction) -} diff --git a/client/src/instructions/mod.rs b/client/src/instructions/mod.rs deleted file mode 100644 index 77b482b..0000000 --- a/client/src/instructions/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod amm_instructions; -pub mod events_instructions_parse; -pub mod rpc; -pub mod token_instructions; -pub mod utils; diff --git a/client/src/instructions/rpc.rs b/client/src/instructions/rpc.rs deleted file mode 100644 index 7dc2ff6..0000000 --- a/client/src/instructions/rpc.rs +++ /dev/null @@ -1,57 +0,0 @@ -use anyhow::{anyhow, Result}; -use solana_client::{ - rpc_client::RpcClient, - rpc_config::RpcSendTransactionConfig, - rpc_request::RpcRequest, - rpc_response::{RpcResult, RpcSimulateTransactionResult}, -}; -use solana_sdk::{ - account::Account, commitment_config::CommitmentConfig, program_pack::Pack as TokenPack, - pubkey::Pubkey, signature::Signature, transaction::Transaction, -}; -use std::convert::Into; - -pub fn simulate_transaction( - client: &RpcClient, - transaction: &Transaction, - sig_verify: bool, - cfg: CommitmentConfig, -) -> RpcResult { - let serialized_encoded = bs58::encode(bincode::serialize(transaction).unwrap()).into_string(); - client.send( - RpcRequest::SimulateTransaction, - serde_json::json!([serialized_encoded, { - "sigVerify": sig_verify, "commitment": cfg.commitment - }]), - ) -} - -pub fn send_txn(client: &RpcClient, txn: &Transaction, wait_confirm: bool) -> Result { - Ok(client.send_and_confirm_transaction_with_spinner_and_config( - txn, - if wait_confirm { - CommitmentConfig::confirmed() - } else { - CommitmentConfig::processed() - }, - RpcSendTransactionConfig { - skip_preflight: true, - ..RpcSendTransactionConfig::default() - }, - )?) -} - -pub fn get_token_account(client: &RpcClient, addr: &Pubkey) -> Result { - let account = client - .get_account_with_commitment(addr, CommitmentConfig::processed())? - .value - .map_or(Err(anyhow!("Account not found")), Ok)?; - T::unpack_from_slice(&account.data).map_err(Into::into) -} - -pub fn get_multiple_accounts( - client: &RpcClient, - pubkeys: &[Pubkey], -) -> Result>> { - Ok(client.get_multiple_accounts(pubkeys)?) -} diff --git a/client/src/instructions/token_instructions.rs b/client/src/instructions/token_instructions.rs deleted file mode 100644 index 67bc07c..0000000 --- a/client/src/instructions/token_instructions.rs +++ /dev/null @@ -1,296 +0,0 @@ -use super::super::{read_keypair_file, ClientConfig}; -use anchor_client::{Client, Cluster}; -use anchor_spl::{ - associated_token::spl_associated_token_account, - token::spl_token, - token_2022::spl_token_2022::{ - self, - extension::{BaseStateWithExtensions, ExtensionType, StateWithExtensionsMut}, - state::{Account, Mint}, - }, -}; -use anyhow::Result; -use solana_client::rpc_client::RpcClient; -use solana_sdk::{ - account::WritableAccount, - instruction::Instruction, - program_pack::Pack, - pubkey::Pubkey, - signature::{Keypair, Signer}, - system_instruction, -}; -// use spl_token_client::token::ExtensionInitializationParams; -use std::{rc::Rc, str::FromStr}; - -// pub fn create_and_init_mint_instr( -// config: &ClientConfig, -// token_program: Pubkey, -// mint_key: &Pubkey, -// mint_authority: &Pubkey, -// freeze_authority: Option<&Pubkey>, -// extension_init_params: Vec, -// decimals: u8, -// ) -> Result> { -// let payer = read_keypair_file(&config.payer_path)?; -// let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); -// // Client. -// let client = Client::new(url, Rc::new(payer)); -// let program = if token_program == spl_token::id() { -// client.program(spl_token::id())? -// } else { -// client.program(spl_token_2022::id())? -// }; -// let extension_types = extension_init_params -// .iter() -// .map(|e| e.extension()) -// .collect::>(); -// let space = ExtensionType::try_calculate_account_len::(&extension_types)?; - -// let mut instructions = vec![system_instruction::create_account( -// &program.payer(), -// mint_key, -// program -// .rpc() -// .get_minimum_balance_for_rent_exemption(space)?, -// space as u64, -// &program.id(), -// )]; -// for params in extension_init_params { -// instructions.push(params.instruction(&token_program, &mint_key)?); -// } -// instructions.push(spl_token_2022::instruction::initialize_mint( -// &program.id(), -// mint_key, -// mint_authority, -// freeze_authority, -// decimals, -// )?); -// Ok(instructions) -// } - -pub fn create_account_rent_exmpt_instr( - config: &ClientConfig, - new_account_key: &Pubkey, - owner: Pubkey, - data_size: usize, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(owner)?; - let instructions = program - .request() - .instruction(system_instruction::create_account( - &program.payer(), - &new_account_key, - program - .rpc() - .get_minimum_balance_for_rent_exemption(data_size)?, - data_size as u64, - &program.id(), - )) - .instructions()?; - Ok(instructions) -} - -pub fn create_ata_token_account_instr( - config: &ClientConfig, - token_program: Pubkey, - mint: &Pubkey, - owner: &Pubkey, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(token_program)?; - let instructions = program - .request() - .instruction( - spl_associated_token_account::instruction::create_associated_token_account_idempotent( - &program.payer(), - owner, - mint, - &token_program, - ), - ) - .instructions()?; - Ok(instructions) -} - -pub fn create_and_init_auxiliary_token( - config: &ClientConfig, - new_account_key: &Pubkey, - mint: &Pubkey, - owner: &Pubkey, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - let mint_account = &mut RpcClient::new(config.http_url.to_string()).get_account(&mint)?; - // Client. - let client = Client::new(url, Rc::new(payer)); - let (program, space) = if mint_account.owner == spl_token::id() { - ( - client.program(spl_token::id())?, - spl_token::state::Account::LEN, - ) - } else { - let mut extensions = vec![]; - extensions.push(ExtensionType::ImmutableOwner); - let mint_state = StateWithExtensionsMut::::unpack(mint_account.data_as_mut_slice())?; - let mint_extension_types = mint_state.get_extension_types()?; - let mut required_extensions = - ExtensionType::get_required_init_account_extensions(&mint_extension_types); - for extension_type in extensions.into_iter() { - if !required_extensions.contains(&extension_type) { - required_extensions.push(extension_type); - } - } - let space = ExtensionType::try_calculate_account_len::(&required_extensions)?; - - (client.program(spl_token_2022::id())?, space) - }; - - let instructions = program - .request() - .instruction(system_instruction::create_account( - &program.payer(), - &mint, - program - .rpc() - .get_minimum_balance_for_rent_exemption(space)?, - space as u64, - &program.id(), - )) - .instruction(spl_token_2022::instruction::initialize_immutable_owner( - &program.id(), - new_account_key, - )?) - .instruction(spl_token_2022::instruction::initialize_account( - &program.id(), - new_account_key, - mint, - owner, - )?) - .instructions()?; - Ok(instructions) -} - -pub fn close_token_account( - config: &ClientConfig, - close_account: &Pubkey, - destination: &Pubkey, - owner: &Keypair, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(spl_token::id())?; - let instructions = program - .request() - .instruction(spl_token::instruction::close_account( - &program.id(), - close_account, - destination, - &owner.pubkey(), - &[], - )?) - .signer(owner) - .instructions()?; - Ok(instructions) -} - -pub fn spl_token_transfer_instr( - config: &ClientConfig, - from: &Pubkey, - to: &Pubkey, - amount: u64, - from_authority: &Keypair, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(spl_token::id())?; - let instructions = program - .request() - .instruction(spl_token::instruction::transfer( - &program.id(), - from, - to, - &from_authority.pubkey(), - &[], - amount, - )?) - .signer(from_authority) - .instructions()?; - Ok(instructions) -} - -pub fn spl_token_mint_to_instr( - config: &ClientConfig, - token_program: Pubkey, - mint: &Pubkey, - to: &Pubkey, - amount: u64, - mint_authority: &Keypair, -) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = if token_program == spl_token::id() { - client.program(spl_token::id())? - } else { - client.program(spl_token_2022::id())? - }; - let instructions = program - .request() - .instruction(spl_token_2022::instruction::mint_to( - &program.id(), - mint, - to, - &mint_authority.pubkey(), - &[], - amount, - )?) - .signer(mint_authority) - .instructions()?; - Ok(instructions) -} - -pub fn wrap_sol_instr(config: &ClientConfig, amount: u64) -> Result> { - let payer = read_keypair_file(&config.payer_path)?; - let wallet_key = payer.pubkey(); - let url = Cluster::Custom(config.http_url.clone(), config.ws_url.clone()); - let wsol_mint = Pubkey::from_str("So11111111111111111111111111111111111111112")?; - let wsol_ata_account = - spl_associated_token_account::get_associated_token_address(&wallet_key, &wsol_mint); - // Client. - let client = Client::new(url, Rc::new(payer)); - let program = client.program(spl_token::id())?; - - let instructions = program - .request() - .instruction( - spl_associated_token_account::instruction::create_associated_token_account_idempotent( - &program.payer(), - &wallet_key, - &wsol_mint, - &program.id(), - ), - ) - .instruction(system_instruction::transfer( - &wallet_key, - &wsol_ata_account, - amount, - )) - .instruction(spl_token::instruction::sync_native( - &program.id(), - &wsol_ata_account, - )?) - .instructions()?; - Ok(instructions) -} diff --git a/client/src/instructions/utils.rs b/client/src/instructions/utils.rs deleted file mode 100644 index ff3f57a..0000000 --- a/client/src/instructions/utils.rs +++ /dev/null @@ -1,136 +0,0 @@ -use anchor_lang::AccountDeserialize; -use anchor_spl::token_2022::spl_token_2022::{ - extension::{ - transfer_fee::{TransferFeeConfig, MAX_FEE_BASIS_POINTS}, - BaseState, BaseStateWithExtensions, PodStateWithExtensions, - }, - pod::{PodAccount, PodMint}, -}; -use anyhow::Result; -use bytemuck::Pod; -use solana_client::rpc_client::RpcClient; -use solana_sdk::{account::Account as CliAccount, pubkey::Pubkey}; -use std::ops::Mul; - -pub fn deserialize_anchor_account(account: &CliAccount) -> Result { - let mut data: &[u8] = &account.data; - T::try_deserialize(&mut data).map_err(Into::into) -} - -pub fn unpack_token(token_data: &[u8]) -> Result> { - let token = PodStateWithExtensions::::unpack(&token_data)?; - Ok(token) -} - -pub fn unpack_mint(token_data: &[u8]) -> Result> { - let mint = PodStateWithExtensions::::unpack(&token_data)?; - Ok(mint) -} - -#[derive(Debug)] -pub struct TransferFeeInfo { - pub mint: Pubkey, - pub owner: Pubkey, - pub transfer_fee: u64, -} - -pub fn amount_with_slippage(amount: u64, slippage: f64, round_up: bool) -> u64 { - if round_up { - (amount as f64).mul(1_f64 + slippage).ceil() as u64 - } else { - (amount as f64).mul(1_f64 - slippage).floor() as u64 - } -} - -pub fn get_pool_mints_inverse_fee( - rpc_client: &RpcClient, - token_mint_0: Pubkey, - token_mint_1: Pubkey, - post_fee_amount_0: u64, - post_fee_amount_1: u64, -) -> (TransferFeeInfo, TransferFeeInfo) { - let load_accounts = vec![token_mint_0, token_mint_1]; - let rsps = rpc_client.get_multiple_accounts(&load_accounts).unwrap(); - let epoch = rpc_client.get_epoch_info().unwrap().epoch; - let mint0_account = rsps[0].clone().ok_or("load mint0 rps error!").unwrap(); - let mint1_account = rsps[1].clone().ok_or("load mint0 rps error!").unwrap(); - let mint0_state = unpack_mint(&mint0_account.data).unwrap(); - let mint1_state = unpack_mint(&mint1_account.data).unwrap(); - ( - TransferFeeInfo { - mint: token_mint_0, - owner: mint0_account.owner, - transfer_fee: get_transfer_inverse_fee(&mint0_state, post_fee_amount_0, epoch), - }, - TransferFeeInfo { - mint: token_mint_1, - owner: mint1_account.owner, - transfer_fee: get_transfer_inverse_fee(&mint1_state, post_fee_amount_1, epoch), - }, - ) -} - -pub fn get_pool_mints_transfer_fee( - rpc_client: &RpcClient, - token_mint_0: Pubkey, - token_mint_1: Pubkey, - pre_fee_amount_0: u64, - pre_fee_amount_1: u64, -) -> (TransferFeeInfo, TransferFeeInfo) { - let load_accounts = vec![token_mint_0, token_mint_1]; - let rsps = rpc_client.get_multiple_accounts(&load_accounts).unwrap(); - let epoch = rpc_client.get_epoch_info().unwrap().epoch; - let mint0_account = rsps[0].clone().ok_or("load mint0 rps error!").unwrap(); - let mint1_account = rsps[1].clone().ok_or("load mint0 rps error!").unwrap(); - let mint0_state = unpack_mint(&mint0_account.data).unwrap(); - let mint1_state = unpack_mint(&mint1_account.data).unwrap(); - ( - TransferFeeInfo { - mint: token_mint_0, - owner: mint0_account.owner, - transfer_fee: get_transfer_fee(&mint0_state, pre_fee_amount_0, epoch), - }, - TransferFeeInfo { - mint: token_mint_1, - owner: mint1_account.owner, - transfer_fee: get_transfer_fee(&mint1_state, pre_fee_amount_1, epoch), - }, - ) -} - -/// Calculate the fee for output amount -pub fn get_transfer_inverse_fee<'data, S: BaseState + Pod>( - account_state: &PodStateWithExtensions<'data, S>, - epoch: u64, - post_fee_amount: u64, -) -> u64 { - let fee = if let Ok(transfer_fee_config) = account_state.get_extension::() { - let transfer_fee = transfer_fee_config.get_epoch_fee(epoch); - if u16::from(transfer_fee.transfer_fee_basis_points) == MAX_FEE_BASIS_POINTS { - u64::from(transfer_fee.maximum_fee) - } else { - transfer_fee_config - .calculate_inverse_epoch_fee(epoch, post_fee_amount) - .unwrap() - } - } else { - 0 - }; - fee -} - -/// Calculate the fee for input amount -pub fn get_transfer_fee<'data, S: BaseState + Pod>( - account_state: &PodStateWithExtensions<'data, S>, - epoch: u64, - pre_fee_amount: u64, -) -> u64 { - let fee = if let Ok(transfer_fee_config) = account_state.get_extension::() { - transfer_fee_config - .calculate_epoch_fee(epoch, pre_fee_amount) - .unwrap() - } else { - 0 - }; - fee -} diff --git a/client/src/main.rs b/client/src/main.rs deleted file mode 100644 index e37b3be..0000000 --- a/client/src/main.rs +++ /dev/null @@ -1,785 +0,0 @@ -#![allow(dead_code)] -use anchor_client::{Client, Cluster}; -use anchor_spl::{associated_token::spl_associated_token_account, token::spl_token}; -use anyhow::{format_err, Result}; -use arrayref::array_ref; -use clap::Parser; -use configparser::ini::Ini; -use solana_client::{rpc_client::RpcClient, rpc_config::RpcTransactionConfig}; -use solana_sdk::{ - commitment_config::CommitmentConfig, - pubkey::Pubkey, - signature::{Keypair, Signature, Signer}, - transaction::Transaction, -}; -use solana_transaction_status::UiTransactionEncoding; -use std::rc::Rc; -use std::str::FromStr; - -mod instructions; -use instructions::amm_instructions::*; -use instructions::events_instructions_parse::*; -use instructions::rpc::*; -use instructions::token_instructions::*; -use instructions::utils::*; -// use spl_token_2022::{ -// extension::StateWithExtensionsMut, -// state::{Account, Mint}, -// }; - -use crate::instructions::utils; - -#[derive(Clone, Debug, PartialEq)] -pub struct ClientConfig { - http_url: String, - ws_url: String, - payer_path: String, - admin_path: String, - raydium_cp_program: Pubkey, - slippage: f64, -} - -fn load_cfg(client_config: &String) -> Result { - let mut config = Ini::new(); - let _map = config.load(client_config).unwrap(); - let http_url = config.get("Global", "http_url").unwrap(); - if http_url.is_empty() { - panic!("http_url must not be empty"); - } - let ws_url = config.get("Global", "ws_url").unwrap(); - if ws_url.is_empty() { - panic!("ws_url must not be empty"); - } - let payer_path = config.get("Global", "payer_path").unwrap(); - if payer_path.is_empty() { - panic!("payer_path must not be empty"); - } - let admin_path = config.get("Global", "admin_path").unwrap(); - if admin_path.is_empty() { - panic!("admin_path must not be empty"); - } - - let raydium_cp_program_str = config.get("Global", "raydium_cp_program").unwrap(); - if raydium_cp_program_str.is_empty() { - panic!("raydium_cp_program must not be empty"); - } - let raydium_cp_program = Pubkey::from_str(&raydium_cp_program_str).unwrap(); - let slippage = config.getfloat("Global", "slippage").unwrap().unwrap(); - - Ok(ClientConfig { - http_url, - ws_url, - payer_path, - admin_path, - raydium_cp_program, - slippage, - }) -} - -fn read_keypair_file(s: &str) -> Result { - solana_sdk::signature::read_keypair_file(s) - .map_err(|_| format_err!("failed to read keypair from {}", s)) -} - -#[derive(Debug, Parser)] -pub struct Opts { - #[clap(subcommand)] - pub command: RaydiumCpCommands, -} - -#[derive(Debug, Parser)] -pub enum RaydiumCpCommands { - InitializePool { - mint0: Pubkey, - mint1: Pubkey, - init_amount_0: u64, - init_amount_1: u64, - #[arg(short, long, default_value_t = 0)] - open_time: u64, - #[clap(short, long, action)] - random_pool: bool, - }, - Deposit { - pool_id: Pubkey, - user_token_0: Pubkey, - user_token_1: Pubkey, - lp_token_amount: u64, - }, - Withdraw { - pool_id: Pubkey, - user_lp_token: Pubkey, - lp_token_amount: u64, - }, - SwapBaseIn { - pool_id: Pubkey, - user_input_token: Pubkey, - user_input_amount: u64, - }, - SwapBaseOut { - pool_id: Pubkey, - user_input_token: Pubkey, - amount_out_less_fee: u64, - }, - DecodeInstruction { - instr_hex_data: String, - }, - DecodeEvent { - log_event: String, - }, - DecodeTxLog { - tx_id: String, - }, -} - -fn main() -> Result<()> { - let client_config = "client_config.ini"; - let pool_config = load_cfg(&client_config.to_string()).unwrap(); - // cluster params. - let payer = read_keypair_file(&pool_config.payer_path)?; - // solana rpc client - let rpc_client = RpcClient::new(pool_config.http_url.to_string()); - - // anchor client. - let anchor_config = pool_config.clone(); - let url = Cluster::Custom(anchor_config.http_url, anchor_config.ws_url); - let wallet = read_keypair_file(&pool_config.payer_path)?; - let anchor_client = Client::new(url, Rc::new(wallet)); - let program = anchor_client.program(pool_config.raydium_cp_program)?; - - let opts = Opts::parse(); - match opts.command { - RaydiumCpCommands::InitializePool { - mint0, - mint1, - init_amount_0, - init_amount_1, - open_time, - random_pool, - } => { - let (mint0, mint1, init_amount_0, init_amount_1) = if mint0 > mint1 { - (mint1, mint0, init_amount_1, init_amount_0) - } else { - (mint0, mint1, init_amount_0, init_amount_1) - }; - let load_pubkeys = vec![mint0, mint1]; - let rsps = rpc_client.get_multiple_accounts(&load_pubkeys)?; - let token_0_program = rsps[0].clone().unwrap().owner; - let token_1_program = rsps[1].clone().unwrap().owner; - - let mut signers = vec![&payer]; - - let random_pool_keypair = Keypair::new(); - let random_pool_id = if random_pool { - let random_pool_id = random_pool_keypair.pubkey(); - println!("random_pool_id:{}", random_pool_id); - signers.push(&random_pool_keypair); - Some(random_pool_id) - } else { - None - }; - - let initialize_pool_instr = initialize_pool_instr( - &pool_config, - mint0, - mint1, - token_0_program, - token_1_program, - spl_associated_token_account::get_associated_token_address_with_program_id( - &payer.pubkey(), - &mint0, - &token_0_program, - ), - spl_associated_token_account::get_associated_token_address_with_program_id( - &payer.pubkey(), - &mint1, - &token_1_program, - ), - raydium_cp_swap::create_pool_fee_reveiver::ID, - random_pool_id, - init_amount_0, - init_amount_1, - open_time, - )?; - - let recent_hash = rpc_client.get_latest_blockhash()?; - let txn = Transaction::new_signed_with_payer( - &initialize_pool_instr, - Some(&payer.pubkey()), - &signers, - recent_hash, - ); - let signature = send_txn(&rpc_client, &txn, true)?; - println!("{}", signature); - } - RaydiumCpCommands::Deposit { - pool_id, - user_token_0, - user_token_1, - lp_token_amount, - } => { - let pool_state: raydium_cp_swap::states::PoolState = program.account(pool_id)?; - // load account - // pool_account and token vault0, token vault1 must be obtained together to ensure data consistency. - let load_pubkeys = vec![pool_id, pool_state.token_0_vault, pool_state.token_1_vault]; - let rsps = rpc_client.get_multiple_accounts(&load_pubkeys)?; - let [pool_account, token_0_vault_account, token_1_vault_account] = - array_ref![rsps, 0, 3]; - // docode account - let pool_state = - utils::deserialize_anchor_account::( - pool_account.as_ref().unwrap(), - ) - .unwrap(); - let token_0_vault_info = unpack_token(&token_0_vault_account.as_ref().unwrap().data)?; - let token_1_vault_info = unpack_token(&token_1_vault_account.as_ref().unwrap().data)?; - - let (total_token_0_amount, total_token_1_amount) = pool_state.vault_amount_without_fee( - u64::from(token_0_vault_info.base.amount), - u64::from(token_1_vault_info.base.amount), - ); - // calculate amount - let results = raydium_cp_swap::curve::CurveCalculator::lp_tokens_to_trading_tokens( - u128::from(lp_token_amount), - u128::from(pool_state.lp_supply), - u128::from(total_token_0_amount), - u128::from(total_token_1_amount), - raydium_cp_swap::curve::RoundDirection::Ceiling, - ) - .ok_or(raydium_cp_swap::error::ErrorCode::ZeroTradingTokens) - .unwrap(); - println!( - "amount_0:{}, amount_1:{}, lp_token_amount:{}", - results.token_0_amount, results.token_1_amount, lp_token_amount - ); - // calc with slippage - let amount_0_with_slippage = - amount_with_slippage(results.token_0_amount as u64, pool_config.slippage, true); - let amount_1_with_slippage = - amount_with_slippage(results.token_1_amount as u64, pool_config.slippage, true); - // calc with transfer_fee - let transfer_fee = get_pool_mints_inverse_fee( - &rpc_client, - pool_state.token_0_mint, - pool_state.token_1_mint, - amount_0_with_slippage, - amount_1_with_slippage, - ); - println!( - "transfer_fee_0:{}, transfer_fee_1:{}", - transfer_fee.0.transfer_fee, transfer_fee.1.transfer_fee - ); - let amount_0_max = (amount_0_with_slippage as u64) - .checked_add(transfer_fee.0.transfer_fee) - .unwrap(); - let amount_1_max = (amount_1_with_slippage as u64) - .checked_add(transfer_fee.1.transfer_fee) - .unwrap(); - println!( - "amount_0_max:{}, amount_1_max:{}", - amount_0_max, amount_1_max - ); - let mut instructions = Vec::new(); - let create_user_lp_token_instr = create_ata_token_account_instr( - &pool_config, - spl_token::id(), - &pool_state.lp_mint, - &payer.pubkey(), - )?; - instructions.extend(create_user_lp_token_instr); - let deposit_instr = deposit_instr( - &pool_config, - pool_id, - pool_state.token_0_mint, - pool_state.token_1_mint, - pool_state.lp_mint, - pool_state.token_0_vault, - pool_state.token_1_vault, - user_token_0, - user_token_1, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.lp_mint, - ), - lp_token_amount, - amount_0_max, - amount_1_max, - )?; - instructions.extend(deposit_instr); - let signers = vec![&payer]; - let recent_hash = rpc_client.get_latest_blockhash()?; - let txn = Transaction::new_signed_with_payer( - &instructions, - Some(&payer.pubkey()), - &signers, - recent_hash, - ); - let signature = send_txn(&rpc_client, &txn, true)?; - println!("{}", signature); - } - RaydiumCpCommands::Withdraw { - pool_id, - user_lp_token, - lp_token_amount, - } => { - let pool_state: raydium_cp_swap::states::PoolState = program.account(pool_id)?; - // load account - // pool_account and token vault0, token vault1 must be obtained together to ensure data consistency. - let load_pubkeys = vec![pool_id, pool_state.token_0_vault, pool_state.token_1_vault]; - let rsps = rpc_client.get_multiple_accounts(&load_pubkeys)?; - let [pool_account, token_0_vault_account, token_1_vault_account] = - array_ref![rsps, 0, 3]; - // docode account - let pool_state = - utils::deserialize_anchor_account::( - pool_account.as_ref().unwrap(), - ) - .unwrap(); - let token_0_vault_info = unpack_token(&token_0_vault_account.as_ref().unwrap().data)?; - let token_1_vault_info = unpack_token(&token_1_vault_account.as_ref().unwrap().data)?; - - let (total_token_0_amount, total_token_1_amount) = pool_state.vault_amount_without_fee( - u64::from(token_0_vault_info.base.amount), - u64::from(token_1_vault_info.base.amount), - ); - // calculate amount - let results = raydium_cp_swap::curve::CurveCalculator::lp_tokens_to_trading_tokens( - u128::from(lp_token_amount), - u128::from(pool_state.lp_supply), - u128::from(total_token_0_amount), - u128::from(total_token_1_amount), - raydium_cp_swap::curve::RoundDirection::Ceiling, - ) - .ok_or(raydium_cp_swap::error::ErrorCode::ZeroTradingTokens) - .unwrap(); - println!( - "amount_0:{}, amount_1:{}, lp_token_amount:{}", - results.token_0_amount, results.token_1_amount, lp_token_amount - ); - - // calc with slippage - let amount_0_with_slippage = - amount_with_slippage(results.token_0_amount as u64, pool_config.slippage, false); - let amount_1_with_slippage = - amount_with_slippage(results.token_1_amount as u64, pool_config.slippage, false); - - let transfer_fee = get_pool_mints_transfer_fee( - &rpc_client, - pool_state.token_0_mint, - pool_state.token_1_mint, - amount_0_with_slippage, - amount_1_with_slippage, - ); - println!( - "transfer_fee_0:{}, transfer_fee_1:{}", - transfer_fee.0.transfer_fee, transfer_fee.1.transfer_fee - ); - let amount_0_min = amount_0_with_slippage - .checked_sub(transfer_fee.0.transfer_fee) - .unwrap(); - let amount_1_min = amount_1_with_slippage - .checked_sub(transfer_fee.1.transfer_fee) - .unwrap(); - println!( - "amount_0_min:{}, amount_1_min:{}", - amount_0_min, amount_1_min - ); - let mut instructions = Vec::new(); - let create_user_token_0_instr = create_ata_token_account_instr( - &pool_config, - spl_token::id(), - &pool_state.token_0_mint, - &payer.pubkey(), - )?; - instructions.extend(create_user_token_0_instr); - let create_user_token_1_instr = create_ata_token_account_instr( - &pool_config, - spl_token::id(), - &pool_state.token_1_mint, - &payer.pubkey(), - )?; - instructions.extend(create_user_token_1_instr); - let withdraw_instr = withdraw_instr( - &pool_config, - pool_id, - pool_state.token_0_mint, - pool_state.token_1_mint, - pool_state.lp_mint, - pool_state.token_0_vault, - pool_state.token_1_vault, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_0_mint, - ), - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_1_mint, - ), - user_lp_token, - lp_token_amount, - amount_0_min, - amount_1_min, - )?; - instructions.extend(withdraw_instr); - let signers = vec![&payer]; - let recent_hash = rpc_client.get_latest_blockhash()?; - let txn = Transaction::new_signed_with_payer( - &instructions, - Some(&payer.pubkey()), - &signers, - recent_hash, - ); - let signature = send_txn(&rpc_client, &txn, true)?; - println!("{}", signature); - } - RaydiumCpCommands::SwapBaseIn { - pool_id, - user_input_token, - user_input_amount, - } => { - let pool_state: raydium_cp_swap::states::PoolState = program.account(pool_id)?; - // load account - // pool_account and token vault0, token vault1 must be obtained together to ensure data consistency. - let load_pubkeys = vec![ - pool_id, - pool_state.amm_config, - pool_state.token_0_vault, - pool_state.token_1_vault, - pool_state.token_0_mint, - pool_state.token_1_mint, - user_input_token, - ]; - let rsps = rpc_client.get_multiple_accounts(&load_pubkeys)?; - let epoch = rpc_client.get_epoch_info().unwrap().epoch; - let [pool_account, amm_config_account, token_0_vault_account, token_1_vault_account, token_0_mint_account, token_1_mint_account, user_input_token_account] = - array_ref![rsps, 0, 7]; - // docode account - let pool_state = - utils::deserialize_anchor_account::( - pool_account.as_ref().unwrap(), - ) - .unwrap(); - let amm_config_state = deserialize_anchor_account::( - amm_config_account.as_ref().unwrap(), - )?; - let token_0_vault_info = unpack_token(&token_0_vault_account.as_ref().unwrap().data)?; - let token_1_vault_info = unpack_token(&token_1_vault_account.as_ref().unwrap().data)?; - let token_0_mint_info = unpack_mint(&token_0_mint_account.as_ref().unwrap().data)?; - let token_1_mint_info = unpack_mint(&token_1_mint_account.as_ref().unwrap().data)?; - let user_input_token_info = - unpack_token(&user_input_token_account.as_ref().unwrap().data)?; - - let (total_token_0_amount, total_token_1_amount) = pool_state.vault_amount_without_fee( - u64::from(token_0_vault_info.base.amount), - u64::from(token_1_vault_info.base.amount), - ); - - let ( - trade_direction, - total_input_token_amount, - total_output_token_amount, - user_input_token, - user_output_token, - input_vault, - output_vault, - input_token_mint, - output_token_mint, - input_token_program, - output_token_program, - transfer_fee, - ) = if user_input_token_info.base.mint == token_0_vault_info.base.mint { - ( - raydium_cp_swap::curve::TradeDirection::ZeroForOne, - total_token_0_amount, - total_token_1_amount, - user_input_token, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_1_mint, - ), - pool_state.token_0_vault, - pool_state.token_1_vault, - pool_state.token_0_mint, - pool_state.token_1_mint, - pool_state.token_0_program, - pool_state.token_1_program, - get_transfer_fee(&token_0_mint_info, epoch, user_input_amount), - ) - } else { - ( - raydium_cp_swap::curve::TradeDirection::OneForZero, - total_token_1_amount, - total_token_0_amount, - user_input_token, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_0_mint, - ), - pool_state.token_1_vault, - pool_state.token_0_vault, - pool_state.token_1_mint, - pool_state.token_0_mint, - pool_state.token_1_program, - pool_state.token_0_program, - get_transfer_fee(&token_1_mint_info, epoch, user_input_amount), - ) - }; - // Take transfer fees into account for actual amount transferred in - let actual_amount_in = user_input_amount.saturating_sub(transfer_fee); - let result = raydium_cp_swap::curve::CurveCalculator::swap_base_input( - u128::from(actual_amount_in), - u128::from(total_input_token_amount), - u128::from(total_output_token_amount), - amm_config_state.trade_fee_rate, - amm_config_state.protocol_fee_rate, - amm_config_state.fund_fee_rate, - ) - .ok_or(raydium_cp_swap::error::ErrorCode::ZeroTradingTokens) - .unwrap(); - let amount_out = u64::try_from(result.destination_amount_swapped).unwrap(); - let transfer_fee = match trade_direction { - raydium_cp_swap::curve::TradeDirection::ZeroForOne => { - get_transfer_fee(&token_1_mint_info, epoch, amount_out) - } - raydium_cp_swap::curve::TradeDirection::OneForZero => { - get_transfer_fee(&token_0_mint_info, epoch, amount_out) - } - }; - let amount_received = amount_out.checked_sub(transfer_fee).unwrap(); - // calc mint out amount with slippage - let minimum_amount_out = - amount_with_slippage(amount_received, pool_config.slippage, false); - - let mut instructions = Vec::new(); - let create_user_output_token_instr = create_ata_token_account_instr( - &pool_config, - spl_token::id(), - &output_token_mint, - &payer.pubkey(), - )?; - instructions.extend(create_user_output_token_instr); - let swap_base_in_instr = swap_base_input_instr( - &pool_config, - pool_id, - pool_state.amm_config, - pool_state.observation_key, - user_input_token, - user_output_token, - input_vault, - output_vault, - input_token_mint, - output_token_mint, - input_token_program, - output_token_program, - user_input_amount, - minimum_amount_out, - )?; - instructions.extend(swap_base_in_instr); - let signers = vec![&payer]; - let recent_hash = rpc_client.get_latest_blockhash()?; - let txn = Transaction::new_signed_with_payer( - &instructions, - Some(&payer.pubkey()), - &signers, - recent_hash, - ); - let signature = send_txn(&rpc_client, &txn, true)?; - println!("{}", signature); - } - RaydiumCpCommands::SwapBaseOut { - pool_id, - user_input_token, - amount_out_less_fee, - } => { - let pool_state: raydium_cp_swap::states::PoolState = program.account(pool_id)?; - // load account - // pool_account and token vault0, token vault1 must be obtained together to ensure data consistency. - let load_pubkeys = vec![ - pool_id, - pool_state.amm_config, - pool_state.token_0_vault, - pool_state.token_1_vault, - pool_state.token_0_mint, - pool_state.token_1_mint, - user_input_token, - ]; - let rsps = rpc_client.get_multiple_accounts(&load_pubkeys)?; - let epoch = rpc_client.get_epoch_info().unwrap().epoch; - let [pool_account, amm_config_account, token_0_vault_account, token_1_vault_account, token_0_mint_account, token_1_mint_account, user_input_token_account] = - array_ref![rsps, 0, 7]; - // docode account - let pool_state = - utils::deserialize_anchor_account::( - pool_account.as_ref().unwrap(), - ) - .unwrap(); - let amm_config_state = deserialize_anchor_account::( - amm_config_account.as_ref().unwrap(), - )?; - let token_0_vault_info = unpack_token(&token_0_vault_account.as_ref().unwrap().data)?; - let token_1_vault_info = unpack_token(&token_1_vault_account.as_ref().unwrap().data)?; - let token_0_mint_info = unpack_mint(&token_0_mint_account.as_ref().unwrap().data)?; - let token_1_mint_info = unpack_mint(&token_1_mint_account.as_ref().unwrap().data)?; - let user_input_token_info = - unpack_token(&user_input_token_account.as_ref().unwrap().data)?; - - let (total_token_0_amount, total_token_1_amount) = pool_state.vault_amount_without_fee( - u64::from(token_0_vault_info.base.amount), - u64::from(token_1_vault_info.base.amount), - ); - - let ( - trade_direction, - total_input_token_amount, - total_output_token_amount, - user_input_token, - user_output_token, - input_vault, - output_vault, - input_token_mint, - output_token_mint, - input_token_program, - output_token_program, - out_transfer_fee, - ) = if user_input_token_info.base.mint == token_0_vault_info.base.mint { - ( - raydium_cp_swap::curve::TradeDirection::ZeroForOne, - total_token_0_amount, - total_token_1_amount, - user_input_token, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_1_mint, - ), - pool_state.token_0_vault, - pool_state.token_1_vault, - pool_state.token_0_mint, - pool_state.token_1_mint, - pool_state.token_0_program, - pool_state.token_1_program, - get_transfer_inverse_fee(&token_1_mint_info, epoch, amount_out_less_fee), - ) - } else { - ( - raydium_cp_swap::curve::TradeDirection::OneForZero, - total_token_1_amount, - total_token_0_amount, - user_input_token, - spl_associated_token_account::get_associated_token_address( - &payer.pubkey(), - &pool_state.token_0_mint, - ), - pool_state.token_1_vault, - pool_state.token_0_vault, - pool_state.token_1_mint, - pool_state.token_0_mint, - pool_state.token_1_program, - pool_state.token_0_program, - get_transfer_inverse_fee(&token_0_mint_info, epoch, amount_out_less_fee), - ) - }; - let actual_amount_out = amount_out_less_fee.checked_add(out_transfer_fee).unwrap(); - - let result = raydium_cp_swap::curve::CurveCalculator::swap_base_output( - u128::from(actual_amount_out), - u128::from(total_input_token_amount), - u128::from(total_output_token_amount), - amm_config_state.trade_fee_rate, - amm_config_state.protocol_fee_rate, - amm_config_state.fund_fee_rate, - ) - .ok_or(raydium_cp_swap::error::ErrorCode::ZeroTradingTokens) - .unwrap(); - - let source_amount_swapped = u64::try_from(result.source_amount_swapped).unwrap(); - let amount_in_transfer_fee = match trade_direction { - raydium_cp_swap::curve::TradeDirection::ZeroForOne => { - get_transfer_inverse_fee(&token_0_mint_info, epoch, source_amount_swapped) - } - raydium_cp_swap::curve::TradeDirection::OneForZero => { - get_transfer_inverse_fee(&token_1_mint_info, epoch, source_amount_swapped) - } - }; - - let input_transfer_amount = source_amount_swapped - .checked_add(amount_in_transfer_fee) - .unwrap(); - // calc max in with slippage - let max_amount_in = - amount_with_slippage(input_transfer_amount, pool_config.slippage, true); - let mut instructions = Vec::new(); - let create_user_output_token_instr = create_ata_token_account_instr( - &pool_config, - spl_token::id(), - &output_token_mint, - &payer.pubkey(), - )?; - instructions.extend(create_user_output_token_instr); - let swap_base_in_instr = swap_base_output_instr( - &pool_config, - pool_id, - pool_state.amm_config, - pool_state.observation_key, - user_input_token, - user_output_token, - input_vault, - output_vault, - input_token_mint, - output_token_mint, - input_token_program, - output_token_program, - max_amount_in, - amount_out_less_fee, - )?; - instructions.extend(swap_base_in_instr); - let signers = vec![&payer]; - let recent_hash = rpc_client.get_latest_blockhash()?; - let txn = Transaction::new_signed_with_payer( - &instructions, - Some(&payer.pubkey()), - &signers, - recent_hash, - ); - let signature = send_txn(&rpc_client, &txn, true)?; - println!("{}", signature); - } - RaydiumCpCommands::DecodeInstruction { instr_hex_data } => { - handle_program_instruction(&instr_hex_data, InstructionDecodeType::BaseHex)?; - } - RaydiumCpCommands::DecodeEvent { log_event } => { - handle_program_log( - &pool_config.raydium_cp_program.to_string(), - &log_event, - false, - )?; - } - RaydiumCpCommands::DecodeTxLog { tx_id } => { - let signature = Signature::from_str(&tx_id)?; - let tx = rpc_client.get_transaction_with_config( - &signature, - RpcTransactionConfig { - encoding: Some(UiTransactionEncoding::Json), - commitment: Some(CommitmentConfig::confirmed()), - max_supported_transaction_version: Some(0), - }, - )?; - let transaction = tx.transaction; - // get meta - let meta = if transaction.meta.is_some() { - transaction.meta - } else { - None - }; - // get encoded_transaction - let encoded_transaction = transaction.transaction; - // decode instruction data - parse_program_instruction( - &pool_config.raydium_cp_program.to_string(), - encoded_transaction, - meta.clone(), - )?; - // decode logs - parse_program_event(&pool_config.raydium_cp_program.to_string(), meta.clone())?; - } - } - Ok(()) -} diff --git a/client_config.ini b/client_config.ini deleted file mode 100644 index 05caa71..0000000 --- a/client_config.ini +++ /dev/null @@ -1,7 +0,0 @@ -[Global] -http_url = https://api.devnet.solana.com -ws_url = wss://api.devnet.solana.com/ -payer_path = id.json -admin_path = adMCyoCgfkg7bQiJ9aBJ59H3BXLY3r5LNLfPpQfMzBe.json -raydium_cp_program = CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW -slippage = 0.01 \ No newline at end of file diff --git a/package.json b/package.json index 1545efe..1c11a02 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,14 @@ { "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", - "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" + "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check", + "test": "./scripts/test-with-light.sh" }, "dependencies": { - "@coral-xyz/anchor": "0.31.0", + "@coral-xyz/anchor": "0.31.1", + "@lightprotocol/compressed-token": "0.22.1-alpha.0", + "@lightprotocol/stateless.js": "0.22.1-alpha.0", + "@noble/hashes": "^1.8.0", "@solana/spl-token": "^0.4.8", "@solana/web3.js": "^1.95.3" }, @@ -18,4 +22,4 @@ "ts-mocha": "^10.0.0", "typescript": "^4.3.5" } -} \ No newline at end of file +} diff --git a/programs/cp-swap/Cargo.toml b/programs/cp-swap/Cargo.toml index bfd49e6..7ba71c3 100644 --- a/programs/cp-swap/Cargo.toml +++ b/programs/cp-swap/Cargo.toml @@ -12,37 +12,51 @@ name = "raydium_cp_swap" [features] no-entrypoint = [] no-log-ix-name = [] +no-idl = [] cpi = ["no-entrypoint"] default = [] enable-log = [] devnet = [] client = [] -idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"] +anchor-debug = [] +idl-build = ["anchor-lang/idl-build", "light-sdk/idl-build", "light-token/idl-build", "light-anchor-spl/idl-build"] test-sbf = [] [dependencies] anchor-lang = { version = "=0.31.1", features = ["init-if-needed", "idl-build"] } -anchor-spl = { version = "=0.31.1", features = ["memo", "metadata", "idl-build"] } spl-token-2022 = { version = "7.0.0", features = ["no-entrypoint"] } spl-math = { version = "0.3", features = ["no-entrypoint"] } uint = "0.10.0" solana-security-txt = "1.1.1" bytemuck = { version = "1.4.0", features = ["derive", "min_const_generics"] } arrayref = { version = "0.3.6" } -light-sdk = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["anchor", "idl-build", "anchor-discriminator-compat"] } -light-sdk-types = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc" } -light-sdk-macros = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc" } -light-hasher = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["solana"] } -light-macros = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["solana"] } +blake3 = { workspace = true } + +light-sdk = { version = "0.18.0", features = ["anchor", "anchor-discriminator", "idl-build", "cpi-context"] } +light-token = { version = "0.3.0", features = ["anchor", "idl-build"] } +light-hasher = "5" +light-anchor-spl = { version = "0.31.1", features = ["idl-build", "memo"] } +solana-account-info = "2.3" +solana-program = "2.2" +solana-pubkey = "2.2" +solana-program-error = "2.2" +solana-cpi = { version = "2.2" } +solana-msg = "2.2" [dev-dependencies] quickcheck = "1.0.3" proptest = "1.0" rand = "0.9.0" -light-program-test = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["v2"] } -light-client = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["v2"] } -light-compressible-client = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc", features = ["anchor"] } -light-test-utils = { git = "https://github.com/lightprotocol/light-protocol", branch = "swen-0011-proc" } + +light-program-test = { version = "0.18.0" } +light-client = { version = "0.18.0" } +tokio = { version = "1", features = ["full"] } +spl-token = "7.0.0" +solana-keypair = { version = "2.2" } +solana-signer = { version = "2.2" } +solana-instruction = { version = "2.2" } +solana-sdk = { version = "2.3" } +bincode = "1.3" [profile.release] @@ -54,3 +68,11 @@ overflow-checks = true opt-level = 3 incremental = false codegen-units = 1 + + +[lints.rust.unexpected_cfgs] +level = "allow" +check-cfg = [ + 'cfg(target_os, values("solana"))', + 'cfg(feature, values("frozen-abi", "no-entrypoint"))', +] diff --git a/programs/cp-swap/src/error.rs b/programs/cp-swap/src/error.rs index 6a711d8..661b41c 100644 --- a/programs/cp-swap/src/error.rs +++ b/programs/cp-swap/src/error.rs @@ -32,4 +32,13 @@ pub enum ErrorCode { InitLpAmountTooLess, #[msg("TransferFee calculate not match")] TransferFeeCalculateNotMatch, + /// ZK Compression. + #[msg("Invalid account count: PDAs and compressed accounts must match")] + InvalidAccountCount, + #[msg("Rent recipient does not match config")] + InvalidRentRecipient, + #[msg("Invalid LP mint address derivation")] + InvalidLpMintAddress, + #[msg("Invalid account data")] + InvalidAccountData, } diff --git a/programs/cp-swap/src/instructions/admin/collect_fund_fee.rs b/programs/cp-swap/src/instructions/admin/collect_fund_fee.rs index f5c1765..068d806 100644 --- a/programs/cp-swap/src/instructions/admin/collect_fund_fee.rs +++ b/programs/cp-swap/src/instructions/admin/collect_fund_fee.rs @@ -2,10 +2,10 @@ use crate::error::ErrorCode; use crate::states::*; use crate::utils::token::*; use anchor_lang::prelude::*; -use anchor_spl::token::Token; -use anchor_spl::token_interface::Mint; -use anchor_spl::token_interface::Token2022; -use anchor_spl::token_interface::TokenAccount; +use light_anchor_spl::token::Token; +use light_anchor_spl::token_interface::Mint; +use light_anchor_spl::token_interface::Token2022; +use light_anchor_spl::token_interface::TokenAccount; #[derive(Accounts)] pub struct CollectFundFee<'info> { /// Only admin or fund_owner can collect fee now @@ -23,23 +23,23 @@ pub struct CollectFundFee<'info> { /// Pool state stores accumulated protocol fee amount #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Account<'info, PoolState>, /// Amm config account stores fund_owner - #[account(address = pool_state.load()?.amm_config)] + #[account(address = pool_state.amm_config)] pub amm_config: Account<'info, AmmConfig>, /// The address that holds pool tokens for token_0 #[account( mut, - constraint = token_0_vault.key() == pool_state.load()?.token_0_vault + constraint = token_0_vault.key() == pool_state.token_0_vault )] pub token_0_vault: Box>, /// The address that holds pool tokens for token_1 #[account( mut, - constraint = token_1_vault.key() == pool_state.load()?.token_1_vault + constraint = token_1_vault.key() == pool_state.token_1_vault )] pub token_1_vault: Box>, @@ -68,6 +68,11 @@ pub struct CollectFundFee<'info> { /// The SPL program 2022 to perform token transfers pub token_program_2022: Program<'info, Token2022>, + + pub system_program: Program<'info, System>, + + /// CHECK: light_token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, } pub fn collect_fund_fee( @@ -79,7 +84,7 @@ pub fn collect_fund_fee( let amount_1: u64; let auth_bump: u8; { - let mut pool_state = ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; amount_0 = amount_0_requested.min(pool_state.fund_fees_token_0); amount_1 = amount_1_requested.min(pool_state.fund_fees_token_1); @@ -88,6 +93,7 @@ pub fn collect_fund_fee( auth_bump = pool_state.auth_bump; pool_state.recent_epoch = Clock::get()?.epoch; } + transfer_from_pool_vault_to_user( ctx.accounts.authority.to_account_info(), ctx.accounts.token_0_vault.to_account_info(), @@ -99,8 +105,10 @@ pub fn collect_fund_fee( ctx.accounts.token_program_2022.to_account_info() }, amount_0, - ctx.accounts.vault_0_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_pool_vault_to_user( @@ -114,8 +122,10 @@ pub fn collect_fund_fee( ctx.accounts.token_program_2022.to_account_info() }, amount_1, - ctx.accounts.vault_1_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; Ok(()) diff --git a/programs/cp-swap/src/instructions/admin/collect_protocol_fee.rs b/programs/cp-swap/src/instructions/admin/collect_protocol_fee.rs index 7f55509..830be27 100644 --- a/programs/cp-swap/src/instructions/admin/collect_protocol_fee.rs +++ b/programs/cp-swap/src/instructions/admin/collect_protocol_fee.rs @@ -2,10 +2,10 @@ use crate::error::ErrorCode; use crate::states::*; use crate::utils::*; use anchor_lang::prelude::*; -use anchor_spl::token::Token; -use anchor_spl::token_interface::Mint; -use anchor_spl::token_interface::Token2022; -use anchor_spl::token_interface::TokenAccount; +use light_anchor_spl::token::Token; +use light_anchor_spl::token_interface::Mint; +use light_anchor_spl::token_interface::Token2022; +use light_anchor_spl::token_interface::TokenAccount; #[derive(Accounts)] pub struct CollectProtocolFee<'info> { @@ -24,23 +24,23 @@ pub struct CollectProtocolFee<'info> { /// Pool state stores accumulated protocol fee amount #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Account<'info, PoolState>, /// Amm config account stores owner - #[account(address = pool_state.load()?.amm_config)] + #[account(address = pool_state.amm_config)] pub amm_config: Account<'info, AmmConfig>, /// The address that holds pool tokens for token_0 #[account( mut, - constraint = token_0_vault.key() == pool_state.load()?.token_0_vault + constraint = token_0_vault.key() == pool_state.token_0_vault )] pub token_0_vault: Box>, /// The address that holds pool tokens for token_1 #[account( mut, - constraint = token_1_vault.key() == pool_state.load()?.token_1_vault + constraint = token_1_vault.key() == pool_state.token_1_vault )] pub token_1_vault: Box>, @@ -69,6 +69,11 @@ pub struct CollectProtocolFee<'info> { /// The SPL program 2022 to perform token transfers pub token_program_2022: Program<'info, Token2022>, + + pub system_program: Program<'info, System>, + + /// CHECK: light_token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, } pub fn collect_protocol_fee( @@ -80,7 +85,7 @@ pub fn collect_protocol_fee( let amount_1: u64; let auth_bump: u8; { - let mut pool_state = ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; amount_0 = amount_0_requested.min(pool_state.protocol_fees_token_0); amount_1 = amount_1_requested.min(pool_state.protocol_fees_token_1); @@ -97,6 +102,7 @@ pub fn collect_protocol_fee( auth_bump = pool_state.auth_bump; pool_state.recent_epoch = Clock::get()?.epoch; } + transfer_from_pool_vault_to_user( ctx.accounts.authority.to_account_info(), ctx.accounts.token_0_vault.to_account_info(), @@ -108,8 +114,10 @@ pub fn collect_protocol_fee( ctx.accounts.token_program_2022.to_account_info() }, amount_0, - ctx.accounts.vault_0_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_pool_vault_to_user( @@ -123,8 +131,10 @@ pub fn collect_protocol_fee( ctx.accounts.token_program_2022.to_account_info() }, amount_1, - ctx.accounts.vault_1_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; Ok(()) diff --git a/programs/cp-swap/src/instructions/admin/update_pool_status.rs b/programs/cp-swap/src/instructions/admin/update_pool_status.rs index 97eec1f..d7a20c9 100644 --- a/programs/cp-swap/src/instructions/admin/update_pool_status.rs +++ b/programs/cp-swap/src/instructions/admin/update_pool_status.rs @@ -9,12 +9,12 @@ pub struct UpdatePoolStatus<'info> { pub authority: Signer<'info>, #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Account<'info, PoolState>, } pub fn update_pool_status(ctx: Context, status: u8) -> Result<()> { require_gte!(255, status); - let mut pool_state = ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; pool_state.set_status(status); pool_state.recent_epoch = Clock::get()?.epoch; Ok(()) diff --git a/programs/cp-swap/src/instructions/deposit.rs b/programs/cp-swap/src/instructions/deposit.rs index 79a4970..814038b 100644 --- a/programs/cp-swap/src/instructions/deposit.rs +++ b/programs/cp-swap/src/instructions/deposit.rs @@ -4,8 +4,10 @@ use crate::error::ErrorCode; use crate::states::*; use crate::utils::token::*; use anchor_lang::prelude::*; -use anchor_spl::token::Token; -use anchor_spl::token_interface::{Mint, Token2022, TokenAccount}; +use light_anchor_spl::token::Token; +use light_anchor_spl::token_interface::Token2022; +use light_token::instruction::MintToCpi; +use light_anchor_spl::token_interface::{TokenAccount, Mint,TokenInterface}; #[derive(Accounts)] pub struct Deposit<'info> { @@ -14,6 +16,7 @@ pub struct Deposit<'info> { /// CHECK: pool vault and lp mint authority #[account( + mut, seeds = [ crate::AUTH_SEED.as_bytes(), ], @@ -22,7 +25,7 @@ pub struct Deposit<'info> { pub authority: UncheckedAccount<'info>, #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Account<'info, PoolState>, /// Owner lp token account #[account(mut, token::authority = owner)] @@ -47,14 +50,14 @@ pub struct Deposit<'info> { /// The address that holds pool tokens for token_0 #[account( mut, - constraint = token_0_vault.key() == pool_state.load()?.token_0_vault + constraint = token_0_vault.key() == pool_state.token_0_vault )] pub token_0_vault: Box>, /// The address that holds pool tokens for token_1 #[account( mut, - constraint = token_1_vault.key() == pool_state.load()?.token_1_vault + constraint = token_1_vault.key() == pool_state.token_1_vault )] pub token_1_vault: Box>, @@ -64,6 +67,9 @@ pub struct Deposit<'info> { /// Token program 2022 pub token_program_2022: Program<'info, Token2022>, + /// CHECK: Light Token program for CPI. + pub light_token_program: Interface<'info, TokenInterface>, + /// The mint of token_0 vault #[account( address = token_0_vault.mint @@ -76,12 +82,17 @@ pub struct Deposit<'info> { )] pub vault_1_mint: Box>, - /// Lp token mint + /// Lp mint #[account( mut, - address = pool_state.load()?.lp_mint @ ErrorCode::IncorrectLpMint) - ] + address = pool_state.lp_mint @ ErrorCode::IncorrectLpMint + )] pub lp_mint: Box>, + + pub system_program: Program<'info, System>, + + /// CHECK: light-token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, } pub fn deposit( @@ -92,7 +103,7 @@ pub fn deposit( ) -> Result<()> { require_gt!(lp_token_amount, 0); let pool_id = ctx.accounts.pool_state.key(); - let pool_state = &mut ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; if !pool_state.get_status_by_bit(PoolStatusBitIndex::Deposit) { return err!(ErrorCode::NotApproved); } @@ -172,7 +183,9 @@ pub fn deposit( ctx.accounts.token_program_2022.to_account_info() }, transfer_token_0_amount, - ctx.accounts.vault_0_mint.decimals, + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_user_to_pool_vault( @@ -186,19 +199,22 @@ pub fn deposit( ctx.accounts.token_program_2022.to_account_info() }, transfer_token_1_amount, - ctx.accounts.vault_1_mint.decimals, + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; pool_state.lp_supply = pool_state.lp_supply.checked_add(lp_token_amount).unwrap(); - token_mint_to( - ctx.accounts.authority.to_account_info(), - ctx.accounts.token_program.to_account_info(), - ctx.accounts.lp_mint.to_account_info(), - ctx.accounts.owner_lp_token.to_account_info(), - lp_token_amount, - &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], - )?; + MintToCpi { + mint: ctx.accounts.lp_mint.to_account_info(), + destination: ctx.accounts.owner_lp_token.to_account_info(), + amount: lp_token_amount, + authority: ctx.accounts.authority.to_account_info(), + system_program: ctx.accounts.system_program.to_account_info(), + max_top_up: None, + } + .invoke_signed(&[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]])?; pool_state.recent_epoch = Clock::get()?.epoch; Ok(()) diff --git a/programs/cp-swap/src/instructions/initialize.rs b/programs/cp-swap/src/instructions/initialize.rs index a4a9a49..111bfbc 100644 --- a/programs/cp-swap/src/instructions/initialize.rs +++ b/programs/cp-swap/src/instructions/initialize.rs @@ -6,78 +6,91 @@ use anchor_lang::{ accounts::interface_account::InterfaceAccount, prelude::*, solana_program::{clock, program::invoke, system_instruction}, - system_program, }; -use anchor_spl::{ +use light_anchor_spl::{ associated_token::AssociatedToken, token::spl_token, token::Token, token_interface::{Mint, TokenAccount, TokenInterface}, }; -use spl_token_2022; -use std::ops::Deref; +use light_sdk::interface::CreateAccountsProof; +use light_token::anchor::LightAccounts; +use light_token::{ + instruction::{ + CreateTokenAccountCpi, CreateTokenAtaCpi, MintToCpi, COMPRESSIBLE_CONFIG_V1, + RENT_SPONSOR as LIGHT_TOKEN_RENT_SPONSOR, + }, + utils::get_token_account_balance, +}; + +pub const LP_MINT_SIGNER_SEED: &[u8] = b"pool_lp_mint"; + +#[derive(AnchorSerialize, AnchorDeserialize, Clone)] +pub struct InitializeParams { + pub init_amount_0: u64, + pub init_amount_1: u64, + pub open_time: u64, + pub create_accounts_proof: CreateAccountsProof, + pub lp_mint_signer_bump: u8, + pub creator_lp_token_bump: u8, + pub authority_bump: u8, +} -#[derive(Accounts)] +#[derive(Accounts, LightAccounts)] +#[instruction(params: InitializeParams)] pub struct Initialize<'info> { - /// Address paying to create the pool. Can be anyone #[account(mut)] pub creator: Signer<'info>, - /// Which config the pool belongs to. pub amm_config: Box>, - /// CHECK: - /// pool vault and lp mint authority #[account( - seeds = [ - crate::AUTH_SEED.as_bytes(), - ], + mut, + seeds = [crate::AUTH_SEED.as_bytes()], bump, )] pub authority: UncheckedAccount<'info>, - /// CHECK: Initialize an account to store the pool state - /// PDA account: - /// seeds = [ - ///     POOL_SEED.as_bytes(), - ///     amm_config.key().as_ref(), - ///     token_0_mint.key().as_ref(), - ///     token_1_mint.key().as_ref(), - /// ], - /// - /// Or random account: must be signed by cli - #[account(mut)] - pub pool_state: UncheckedAccount<'info>, + #[account( + init, + seeds = [ + POOL_SEED.as_bytes(), + amm_config.key().as_ref(), + token_0_mint.key().as_ref(), + token_1_mint.key().as_ref(), + ], + bump, + payer = creator, + space = 8 + PoolState::INIT_SPACE + )] + #[light_account(init)] + pub pool_state: Box>, - /// Token_0 mint, the key must smaller than token_1 mint. #[account( constraint = token_0_mint.key() < token_1_mint.key(), mint::token_program = token_0_program, )] pub token_0_mint: Box>, - /// Token_1 mint, the key must grater then token_0 mint. - #[account( - mint::token_program = token_1_program, - )] + #[account(mint::token_program = token_1_program)] pub token_1_mint: Box>, - /// pool lp mint #[account( - init, - seeds = [ - POOL_LP_MINT_SEED.as_bytes(), - pool_state.key().as_ref(), - ], + seeds = [LP_MINT_SIGNER_SEED, pool_state.key().as_ref()], bump, - mint::decimals = 9, - mint::authority = authority, - payer = creator, - mint::token_program = token_program, )] - pub lp_mint: Box>, + pub lp_mint_signer: UncheckedAccount<'info>, + + #[account(mut)] + #[light_account(init, mint, + mint_signer = lp_mint_signer, + authority = authority, + decimals = 9, + mint_seeds = &[LP_MINT_SIGNER_SEED, self.pool_state.to_account_info().key.as_ref(), &[params.lp_mint_signer_bump]], + authority_seeds = &[crate::AUTH_SEED.as_bytes(), &[params.authority_bump]] + )] + pub lp_mint: UncheckedAccount<'info>, - /// payer token0 account #[account( mut, token::mint = token_0_mint, @@ -85,7 +98,6 @@ pub struct Initialize<'info> { )] pub creator_token_0: Box>, - /// creator token1 account #[account( mut, token::mint = token_1_mint, @@ -93,17 +105,9 @@ pub struct Initialize<'info> { )] pub creator_token_1: Box>, - /// creator lp token account - #[account( - init, - associated_token::mint = lp_mint, - associated_token::authority = creator, - payer = creator, - token::token_program = token_program, - )] - pub creator_lp_token: Box>, + #[account(mut)] + pub creator_lp_token: UncheckedAccount<'info>, - /// CHECK: Token_0 vault for the pool, created by contract #[account( mut, seeds = [ @@ -113,9 +117,9 @@ pub struct Initialize<'info> { ], bump, )] + #[light_account(token, authority = [crate::AUTH_SEED.as_bytes()])] pub token_0_vault: UncheckedAccount<'info>, - /// CHECK: Token_1 vault for the pool, created by contract #[account( mut, seeds = [ @@ -125,48 +129,50 @@ pub struct Initialize<'info> { ], bump, )] + #[light_account(token, authority = [crate::AUTH_SEED.as_bytes()])] pub token_1_vault: UncheckedAccount<'info>, - /// create pool fee account - #[account( - mut, - address= crate::create_pool_fee_reveiver::ID, - )] - pub create_pool_fee: Box>, - - /// an account to store oracle observations #[account( init, - seeds = [ - OBSERVATION_SEED.as_bytes(), - pool_state.key().as_ref(), - ], + seeds = [OBSERVATION_SEED.as_bytes(), pool_state.key().as_ref()], bump, payer = creator, - space = ObservationState::LEN + space = 8 + ObservationState::INIT_SPACE )] - pub observation_state: AccountLoader<'info, ObservationState>, + #[light_account(init)] + pub observation_state: Box>, + + #[account(mut, address = crate::create_pool_fee_receiver::ID)] + pub create_pool_fee: Box>, - /// Program to create mint account and mint tokens pub token_program: Program<'info, Token>, - /// Spl token program or token program 2022 pub token_0_program: Interface<'info, TokenInterface>, - /// Spl token program or token program 2022 pub token_1_program: Interface<'info, TokenInterface>, - /// Program to create an ATA for receiving position NFT pub associated_token_program: Program<'info, AssociatedToken>, - /// To create a new program account pub system_program: Program<'info, System>, - /// Sysvar for program account pub rent: Sysvar<'info, Rent>, + + pub compression_config: AccountInfo<'info>, + + #[account(address = COMPRESSIBLE_CONFIG_V1)] + pub light_token_compressible_config: AccountInfo<'info>, + + #[account(mut, address = LIGHT_TOKEN_RENT_SPONSOR)] + pub light_token_rent_sponsor: AccountInfo<'info>, + + pub light_token_program: AccountInfo<'info>, + + /// CHECK: light-token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, } -pub fn initialize( - ctx: Context, - init_amount_0: u64, - init_amount_1: u64, - mut open_time: u64, +pub fn initialize<'info>( + ctx: Context<'_, '_, '_, 'info, Initialize<'info>>, + params: InitializeParams, ) -> Result<()> { + let init_amount_0 = params.init_amount_0; + let init_amount_1 = params.init_amount_1; + let mut open_time = params.open_time; if !(is_supported_mint(&ctx.accounts.token_0_mint).unwrap() && is_supported_mint(&ctx.accounts.token_1_mint).unwrap()) { @@ -176,54 +182,56 @@ pub fn initialize( if ctx.accounts.amm_config.disable_create_pool { return err!(ErrorCode::NotApproved); } + let block_timestamp = clock::Clock::get()?.unix_timestamp as u64; - if open_time <= block_timestamp { + // open_time=0 means immediately open (no bump) + if open_time != 0 && open_time <= block_timestamp { open_time = block_timestamp + 1; } - // due to stack/heap limitations, we have to create redundant new accounts ourselves. - create_token_account( - &ctx.accounts.authority.to_account_info(), - &ctx.accounts.creator.to_account_info(), - &ctx.accounts.token_0_vault.to_account_info(), - &ctx.accounts.token_0_mint.to_account_info(), - &ctx.accounts.system_program.to_account_info(), - &ctx.accounts.token_0_program.to_account_info(), - &[ - POOL_VAULT_SEED.as_bytes(), - ctx.accounts.pool_state.key().as_ref(), - ctx.accounts.token_0_mint.key().as_ref(), - &[ctx.bumps.token_0_vault][..], - ], - )?; - - create_token_account( - &ctx.accounts.authority.to_account_info(), - &ctx.accounts.creator.to_account_info(), - &ctx.accounts.token_1_vault.to_account_info(), - &ctx.accounts.token_1_mint.to_account_info(), - &ctx.accounts.system_program.to_account_info(), - &ctx.accounts.token_1_program.to_account_info(), - &[ - POOL_VAULT_SEED.as_bytes(), - ctx.accounts.pool_state.key().as_ref(), - ctx.accounts.token_1_mint.key().as_ref(), - &[ctx.bumps.token_1_vault][..], - ], - )?; - - let pool_state_loader = create_pool( - &ctx.accounts.creator.to_account_info(), - &ctx.accounts.pool_state.to_account_info(), - &ctx.accounts.amm_config.to_account_info(), - &ctx.accounts.token_0_mint.to_account_info(), - &ctx.accounts.token_1_mint.to_account_info(), - &ctx.accounts.system_program.to_account_info(), - )?; - let pool_state = &mut pool_state_loader.load_init()?; - let mut observation_state = ctx.accounts.observation_state.load_init()?; - observation_state.pool_id = ctx.accounts.pool_state.key(); + let pool_state_key = ctx.accounts.pool_state.key(); + // Create token_0 vault + CreateTokenAccountCpi { + payer: ctx.accounts.creator.to_account_info(), + account: ctx.accounts.token_0_vault.to_account_info(), + mint: ctx.accounts.token_0_mint.to_account_info(), + owner: ctx.accounts.authority.key(), + } + .rent_free( + ctx.accounts.light_token_compressible_config.to_account_info(), + ctx.accounts.light_token_rent_sponsor.to_account_info(), + ctx.accounts.system_program.to_account_info(), + &crate::ID, + ) + .invoke_signed(&[ + POOL_VAULT_SEED.as_bytes(), + pool_state_key.as_ref(), + ctx.accounts.token_0_mint.key().as_ref(), + &[ctx.bumps.token_0_vault], + ])?; + + // Create token_1 vault + CreateTokenAccountCpi { + payer: ctx.accounts.creator.to_account_info(), + account: ctx.accounts.token_1_vault.to_account_info(), + mint: ctx.accounts.token_1_mint.to_account_info(), + owner: ctx.accounts.authority.key(), + } + .rent_free( + ctx.accounts.light_token_compressible_config.to_account_info(), + ctx.accounts.light_token_rent_sponsor.to_account_info(), + ctx.accounts.system_program.to_account_info(), + &crate::ID, + ) + .invoke_signed(&[ + POOL_VAULT_SEED.as_bytes(), + pool_state_key.as_ref(), + ctx.accounts.token_1_mint.key().as_ref(), + &[ctx.bumps.token_1_vault], + ])?; + + // Transfer tokens from creator to vaults transfer_from_user_to_pool_vault( ctx.accounts.creator.to_account_info(), ctx.accounts.creator_token_0.to_account_info(), @@ -231,7 +239,9 @@ pub fn initialize( ctx.accounts.token_0_mint.to_account_info(), ctx.accounts.token_0_program.to_account_info(), init_amount_0, - ctx.accounts.token_0_mint.decimals, + ctx.accounts.creator.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_user_to_pool_vault( @@ -241,53 +251,20 @@ pub fn initialize( ctx.accounts.token_1_mint.to_account_info(), ctx.accounts.token_1_program.to_account_info(), init_amount_1, - ctx.accounts.token_1_mint.decimals, + ctx.accounts.creator.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; - let token_0_vault = - spl_token_2022::extension::StateWithExtensions::::unpack( - ctx.accounts - .token_0_vault - .to_account_info() - .try_borrow_data()? - .deref(), - )? - .base; - let token_1_vault = - spl_token_2022::extension::StateWithExtensions::::unpack( - ctx.accounts - .token_1_vault - .to_account_info() - .try_borrow_data()? - .deref(), - )? - .base; - - CurveCalculator::validate_supply(token_0_vault.amount, token_1_vault.amount)?; - - let liquidity = U128::from(token_0_vault.amount) - .checked_mul(token_1_vault.amount.into()) - .unwrap() - .integer_sqrt() - .as_u64(); - let lock_lp_amount = 100; - msg!( - "liquidity:{}, lock_lp_amount:{}, vault_0_amount:{},vault_1_amount:{}", - liquidity, - lock_lp_amount, - token_0_vault.amount, - token_1_vault.amount - ); - token::token_mint_to( - ctx.accounts.authority.to_account_info(), - ctx.accounts.token_program.to_account_info(), - ctx.accounts.lp_mint.to_account_info(), - ctx.accounts.creator_lp_token.to_account_info(), - liquidity - .checked_sub(lock_lp_amount) - .ok_or(ErrorCode::InitLpAmountTooLess)?, - &[&[crate::AUTH_SEED.as_bytes(), &[ctx.bumps.authority]]], - )?; + // Get vault balances - supports both light token and spl token accounts + let token_0_vault_balance = + get_token_account_balance(&ctx.accounts.token_0_vault.to_account_info()) + .map_err(|_| ErrorCode::InvalidAccountData)?; + let token_1_vault_balance = + get_token_account_balance(&ctx.accounts.token_1_vault.to_account_info()) + .map_err(|_| ErrorCode::InvalidAccountData)?; + + CurveCalculator::validate_supply(token_0_vault_balance, token_1_vault_balance)?; // Charge the fee to create a pool if ctx.accounts.amm_config.create_pool_fee != 0 { @@ -315,6 +292,22 @@ pub fn initialize( )?; } + let liquidity = U128::from(token_0_vault_balance) + .checked_mul(token_1_vault_balance.into()) + .unwrap() + .integer_sqrt() + .as_u64(); + let lock_lp_amount = 100; + + let user_lp_amount = liquidity + .checked_sub(lock_lp_amount) + .ok_or(ErrorCode::InitLpAmountTooLess)?; + + let pool_state = &mut ctx.accounts.pool_state; + let observation_state = &mut ctx.accounts.observation_state; + let observation_state_key = observation_state.key(); + observation_state.pool_id = pool_state_key; + pool_state.initialize( ctx.bumps.authority, liquidity, @@ -326,55 +319,35 @@ pub fn initialize( &ctx.accounts.token_0_mint, &ctx.accounts.token_1_mint, &ctx.accounts.lp_mint, - ctx.accounts.observation_state.key(), + observation_state_key, ); - Ok(()) -} - -pub fn create_pool<'info>( - payer: &AccountInfo<'info>, - pool_account_info: &AccountInfo<'info>, - amm_config: &AccountInfo<'info>, - token_0_mint: &AccountInfo<'info>, - token_1_mint: &AccountInfo<'info>, - system_program: &AccountInfo<'info>, -) -> Result> { - if pool_account_info.owner != &system_program::ID { - return err!(ErrorCode::NotApproved); + // Create creator LP token ATA + CreateTokenAtaCpi { + payer: ctx.accounts.creator.to_account_info(), + owner: ctx.accounts.creator.to_account_info(), + mint: ctx.accounts.lp_mint.to_account_info(), + ata: ctx.accounts.creator_lp_token.to_account_info(), + bump: params.creator_lp_token_bump, } - - let (expect_pda_address, bump) = Pubkey::find_program_address( - &[ - POOL_SEED.as_bytes(), - amm_config.key().as_ref(), - token_0_mint.key().as_ref(), - token_1_mint.key().as_ref(), - ], - &crate::id(), - ); - - if pool_account_info.key() != expect_pda_address { - require_eq!(pool_account_info.is_signer, true); + .idempotent() + .rent_free( + ctx.accounts.light_token_compressible_config.to_account_info(), + ctx.accounts.light_token_rent_sponsor.to_account_info(), + ctx.accounts.system_program.to_account_info(), + ) + .invoke()?; + + // Mint LP tokens to creator + MintToCpi { + mint: ctx.accounts.lp_mint.to_account_info(), + destination: ctx.accounts.creator_lp_token.to_account_info(), + amount: user_lp_amount, + authority: ctx.accounts.authority.to_account_info(), + system_program: ctx.accounts.system_program.to_account_info(), + max_top_up: None, } + .invoke_signed(&[&[crate::AUTH_SEED.as_bytes(), &[ctx.bumps.authority]]])?; - token::create_or_allocate_account( - &crate::id(), - payer.to_account_info(), - system_program.to_account_info(), - pool_account_info.clone(), - &[ - POOL_SEED.as_bytes(), - amm_config.key().as_ref(), - token_0_mint.key().as_ref(), - token_1_mint.key().as_ref(), - &[bump], - ], - PoolState::LEN, - )?; - - Ok(AccountLoad::::try_from_unchecked( - &crate::id(), - &pool_account_info, - )?) + Ok(()) } diff --git a/programs/cp-swap/src/instructions/swap_base_input.rs b/programs/cp-swap/src/instructions/swap_base_input.rs index f93a49a..1c686a0 100644 --- a/programs/cp-swap/src/instructions/swap_base_input.rs +++ b/programs/cp-swap/src/instructions/swap_base_input.rs @@ -5,7 +5,7 @@ use crate::states::*; use crate::utils::token::*; use anchor_lang::prelude::*; use anchor_lang::solana_program; -use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; +use light_anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; #[derive(Accounts)] pub struct Swap<'info> { @@ -22,12 +22,12 @@ pub struct Swap<'info> { pub authority: UncheckedAccount<'info>, /// The factory state to read protocol fees - #[account(address = pool_state.load()?.amm_config)] + #[account(address = pool_state.amm_config)] pub amm_config: Box>, /// The program account of the pool in which the swap will be performed #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Box>, /// The user token account for input token #[account(mut)] @@ -40,14 +40,14 @@ pub struct Swap<'info> { /// The vault token account for input token #[account( mut, - constraint = input_vault.key() == pool_state.load()?.token_0_vault || input_vault.key() == pool_state.load()?.token_1_vault + constraint = input_vault.key() == pool_state.token_0_vault || input_vault.key() == pool_state.token_1_vault )] pub input_vault: Box>, /// The vault token account for output token #[account( mut, - constraint = output_vault.key() == pool_state.load()?.token_0_vault || output_vault.key() == pool_state.load()?.token_1_vault + constraint = output_vault.key() == pool_state.token_0_vault || output_vault.key() == pool_state.token_1_vault )] pub output_vault: Box>, @@ -69,14 +69,22 @@ pub struct Swap<'info> { )] pub output_token_mint: Box>, /// The program account for the most recent oracle observation - #[account(mut, address = pool_state.load()?.observation_key)] - pub observation_state: AccountLoader<'info, ObservationState>, + #[account(mut, address = pool_state.observation_key)] + pub observation_state: Account<'info, ObservationState>, + + /// Light Token program for CPI + pub light_token_program: Interface<'info, TokenInterface>, + + pub system_program: Program<'info, System>, + + /// CHECK: light_token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, } pub fn swap_base_input(ctx: Context, amount_in: u64, minimum_amount_out: u64) -> Result<()> { let block_timestamp = solana_program::clock::Clock::get()?.unix_timestamp as u64; let pool_id = ctx.accounts.pool_state.key(); - let pool_state = &mut ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; if !pool_state.get_status_by_bit(PoolStatusBitIndex::Swap) || block_timestamp < pool_state.open_time { @@ -232,7 +240,9 @@ pub fn swap_base_input(ctx: Context, amount_in: u64, minimum_amount_out: u ctx.accounts.input_token_mint.to_account_info(), ctx.accounts.input_token_program.to_account_info(), input_transfer_amount, - ctx.accounts.input_token_mint.decimals, + ctx.accounts.payer.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_pool_vault_to_user( @@ -242,12 +252,14 @@ pub fn swap_base_input(ctx: Context, amount_in: u64, minimum_amount_out: u ctx.accounts.output_token_mint.to_account_info(), ctx.accounts.output_token_program.to_account_info(), output_transfer_amount, - ctx.accounts.output_token_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], + ctx.accounts.payer.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; // update the previous price to the observation - ctx.accounts.observation_state.load_mut()?.update( + ctx.accounts.observation_state.update( oracle::block_timestamp(), token_0_price_x64, token_1_price_x64, diff --git a/programs/cp-swap/src/instructions/swap_base_output.rs b/programs/cp-swap/src/instructions/swap_base_output.rs index 2ba3731..853e460 100644 --- a/programs/cp-swap/src/instructions/swap_base_output.rs +++ b/programs/cp-swap/src/instructions/swap_base_output.rs @@ -14,7 +14,7 @@ pub fn swap_base_output( require_gt!(amount_out_less_fee, 0); let block_timestamp = solana_program::clock::Clock::get()?.unix_timestamp as u64; let pool_id = ctx.accounts.pool_state.key(); - let pool_state = &mut ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; if !pool_state.get_status_by_bit(PoolStatusBitIndex::Swap) || block_timestamp < pool_state.open_time { @@ -172,7 +172,9 @@ pub fn swap_base_output( ctx.accounts.input_token_mint.to_account_info(), ctx.accounts.input_token_program.to_account_info(), input_transfer_amount, - ctx.accounts.input_token_mint.decimals, + ctx.accounts.payer.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_pool_vault_to_user( @@ -182,12 +184,14 @@ pub fn swap_base_output( ctx.accounts.output_token_mint.to_account_info(), ctx.accounts.output_token_program.to_account_info(), output_transfer_amount, - ctx.accounts.output_token_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], + ctx.accounts.payer.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; // update the previous price to the observation - ctx.accounts.observation_state.load_mut()?.update( + ctx.accounts.observation_state.update( oracle::block_timestamp(), token_0_price_x64, token_1_price_x64, diff --git a/programs/cp-swap/src/instructions/withdraw.rs b/programs/cp-swap/src/instructions/withdraw.rs index 6b60722..484d08b 100644 --- a/programs/cp-swap/src/instructions/withdraw.rs +++ b/programs/cp-swap/src/instructions/withdraw.rs @@ -4,11 +4,12 @@ use crate::error::ErrorCode; use crate::states::*; use crate::utils::token::*; use anchor_lang::prelude::*; -use anchor_spl::{ +use light_anchor_spl::{ memo::spl_memo, token::Token, - token_interface::{Mint, Token2022, TokenAccount}, + token_interface::{Mint, Token2022, TokenAccount, TokenInterface}, }; +use light_token::instruction::BurnCpi; #[derive(Accounts)] pub struct Withdraw<'info> { @@ -26,11 +27,10 @@ pub struct Withdraw<'info> { /// Pool state account #[account(mut)] - pub pool_state: AccountLoader<'info, PoolState>, + pub pool_state: Box>, - /// Owner lp token account #[account( - mut, + mut, token::authority = owner )] pub owner_lp_token: Box>, @@ -52,14 +52,14 @@ pub struct Withdraw<'info> { /// The address that holds pool tokens for token_0 #[account( mut, - constraint = token_0_vault.key() == pool_state.load()?.token_0_vault + constraint = token_0_vault.key() == pool_state.token_0_vault )] pub token_0_vault: Box>, /// The address that holds pool tokens for token_1 #[account( mut, - constraint = token_1_vault.key() == pool_state.load()?.token_1_vault + constraint = token_1_vault.key() == pool_state.token_1_vault )] pub token_1_vault: Box>, @@ -81,11 +81,11 @@ pub struct Withdraw<'info> { )] pub vault_1_mint: Box>, - /// Pool lp token mint + /// Lp mint #[account( mut, - address = pool_state.load()?.lp_mint @ ErrorCode::IncorrectLpMint) - ] + address = pool_state.lp_mint @ ErrorCode::IncorrectLpMint + )] pub lp_mint: Box>, /// memo program @@ -94,6 +94,14 @@ pub struct Withdraw<'info> { address = spl_memo::id() )] pub memo_program: UncheckedAccount<'info>, + + pub system_program: Program<'info, System>, + + /// CHECK: light-token CPI authority. + pub light_token_cpi_authority: AccountInfo<'info>, + + /// Light Token program for CPI + pub light_token_program: Interface<'info, TokenInterface>, } pub fn withdraw( @@ -103,9 +111,8 @@ pub fn withdraw( minimum_token_1_amount: u64, ) -> Result<()> { require_gt!(lp_token_amount, 0); - require_gt!(ctx.accounts.lp_mint.supply, 0); let pool_id = ctx.accounts.pool_state.key(); - let pool_state = &mut ctx.accounts.pool_state.load_mut()?; + let pool_state = &mut ctx.accounts.pool_state; if !pool_state.get_status_by_bit(PoolStatusBitIndex::Withdraw) { return err!(ErrorCode::NotApproved); } @@ -175,15 +182,16 @@ pub fn withdraw( return Err(ErrorCode::ExceededSlippage.into()); } + BurnCpi { + source: ctx.accounts.owner_lp_token.to_account_info(), + mint: ctx.accounts.lp_mint.to_account_info(), + amount: lp_token_amount, + authority: ctx.accounts.owner.to_account_info(), + max_top_up: None, + } + .invoke()?; + pool_state.lp_supply = pool_state.lp_supply.checked_sub(lp_token_amount).unwrap(); - token_burn( - ctx.accounts.owner.to_account_info(), - ctx.accounts.token_program.to_account_info(), - ctx.accounts.lp_mint.to_account_info(), - ctx.accounts.owner_lp_token.to_account_info(), - lp_token_amount, - &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], - )?; transfer_from_pool_vault_to_user( ctx.accounts.authority.to_account_info(), @@ -196,8 +204,10 @@ pub fn withdraw( ctx.accounts.token_program_2022.to_account_info() }, token_0_amount, - ctx.accounts.vault_0_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; transfer_from_pool_vault_to_user( @@ -211,8 +221,10 @@ pub fn withdraw( ctx.accounts.token_program_2022.to_account_info() }, token_1_amount, - ctx.accounts.vault_1_mint.decimals, &[&[crate::AUTH_SEED.as_bytes(), &[pool_state.auth_bump]]], + ctx.accounts.owner.to_account_info(), + ctx.accounts.light_token_cpi_authority.to_account_info(), + ctx.accounts.system_program.to_account_info(), )?; pool_state.recent_epoch = Clock::get()?.epoch; diff --git a/programs/cp-swap/src/lib.rs b/programs/cp-swap/src/lib.rs index 516a83b..2d80571 100644 --- a/programs/cp-swap/src/lib.rs +++ b/programs/cp-swap/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] + pub mod curve; pub mod error; pub mod instructions; @@ -5,8 +7,16 @@ pub mod states; pub mod utils; use crate::curve::fees::FEE_RATE_DENOMINATOR_VALUE; +pub use crate::instructions::initialize::{Initialize, InitializeParams}; +pub use crate::states::{ + ObservationState, PackedObservationState, PackedPoolState, PoolState, OBSERVATION_SEED, + POOL_SEED, POOL_VAULT_SEED, +}; use anchor_lang::prelude::*; use instructions::*; +use light_token::anchor::{ + derive_light_cpi_signer, derive_light_rent_sponsor_pda, light_program, CpiSigner, +}; #[cfg(not(feature = "no-entrypoint"))] solana_security_txt::security_txt! { @@ -24,15 +34,29 @@ declare_id!("CPMDWBwJDtYax9qW7AyRuVC19Cc4L4Vcy4n2BHAbHkCW"); #[cfg(not(feature = "devnet"))] declare_id!("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"); +pub const LIGHT_CPI_SIGNER: CpiSigner = + derive_light_cpi_signer!("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"); + +pub const PROGRAM_RENT_SPONSOR_DATA: ([u8; 32], u8) = + derive_light_rent_sponsor_pda!("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C", 1); + +#[inline] +pub fn program_rent_sponsor() -> Pubkey { + Pubkey::from(PROGRAM_RENT_SPONSOR_DATA.0) +} + pub mod admin { use super::{pubkey, Pubkey}; #[cfg(feature = "devnet")] pub const ID: Pubkey = pubkey!("adMCyoCgfkg7bQiJ9aBJ59H3BXLY3r5LNLfPpQfMzBe"); - #[cfg(not(feature = "devnet"))] - pub const ID: Pubkey = pubkey!("GThUX1Atko4tqhN2NaiTazWSeFWMuiUvfFnyJyUghFMJ"); + #[cfg(all(not(feature = "devnet"), not(feature = "test-sbf")))] + pub const ID: Pubkey = pubkey!("AKnL4NNf3DGWZJS6cPknBuEGnVsV4A4m5tgebLHaRSZ9"); + // Test admin - pubkey derived from Keypair::from_seed(&[1u8; 32]) + #[cfg(feature = "test-sbf")] + pub const ID: Pubkey = pubkey!("AKnL4NNf3DGWZJS6cPknBuEGnVsV4A4m5tgebLHaRSZ9"); } -pub mod create_pool_fee_reveiver { +pub mod create_pool_fee_receiver { use super::{pubkey, Pubkey}; #[cfg(feature = "devnet")] pub const ID: Pubkey = pubkey!("G11FKBRaAkHAKuLCgLM6K6NUc9rTjPAznRCjZifrTQe2"); @@ -42,11 +66,15 @@ pub mod create_pool_fee_reveiver { pub const AUTH_SEED: &str = "vault_and_lp_mint_auth_seed"; +#[light_program] #[program] pub mod raydium_cp_swap { + #![allow(clippy::too_many_arguments)] + use super::*; - // The configuration of AMM protocol, include trade fee and protocol fee + /// The configuration of AMM protocol, include trade fee and protocol fee + /// /// # Arguments /// /// * `ctx`- The accounts needed by instruction. @@ -142,17 +170,13 @@ pub mod raydium_cp_swap { /// # Arguments /// /// * `ctx`- The context of accounts - /// * `init_amount_0` - the initial amount_0 to deposit - /// * `init_amount_1` - the initial amount_1 to deposit - /// * `open_time` - the timestamp allowed for swap - /// - pub fn initialize( - ctx: Context, - init_amount_0: u64, - init_amount_1: u64, - open_time: u64, + /// * `params` - Initialize parameters including init_amount_0, init_amount_1, open_time + /// + pub fn initialize<'info>( + ctx: Context<'_, '_, '_, 'info, Initialize<'info>>, + params: InitializeParams, ) -> Result<()> { - instructions::initialize(ctx, init_amount_0, init_amount_1, open_time) + instructions::initialize(ctx, params) } /// Deposit lp token to the pool diff --git a/programs/cp-swap/src/states/oracle.rs b/programs/cp-swap/src/states/oracle.rs index ed7173b..2b4e798 100644 --- a/programs/cp-swap/src/states/oracle.rs +++ b/programs/cp-swap/src/states/oracle.rs @@ -1,76 +1,33 @@ -/// Oracle provides price data useful for a wide variety of system designs -/// use anchor_lang::prelude::*; +use light_sdk::LightDiscriminator; +use light_token::anchor::{CompressionInfo, LightAccount}; + #[cfg(test)] use std::time::{SystemTime, UNIX_EPOCH}; -/// Seed to derive account address and signature + pub const OBSERVATION_SEED: &str = "observation"; -// Number of ObservationState element -pub const OBSERVATION_NUM: usize = 100; +pub const OBSERVATION_NUM: usize = 2; pub const OBSERVATION_UPDATE_DURATION_DEFAULT: u64 = 15; -/// The element of observations in ObservationState -#[zero_copy(unsafe)] -#[repr(C, packed)] -#[derive(Default, Debug)] +#[derive(Default, Clone, Copy, AnchorSerialize, AnchorDeserialize, InitSpace, Debug)] pub struct Observation { - /// The block timestamp of the observation pub block_timestamp: u64, - /// the cumulative of token0 price during the duration time, Q32.32, the remaining 64 bit for overflow pub cumulative_token_0_price_x32: u128, - /// the cumulative of token1 price during the duration time, Q32.32, the remaining 64 bit for overflow pub cumulative_token_1_price_x32: u128, } -impl Observation { - pub const LEN: usize = 8 + 16 + 16; -} -#[account(zero_copy(unsafe))] -#[repr(C, packed)] -#[cfg_attr(feature = "client", derive(Debug))] +#[derive(Default, Debug, InitSpace, LightAccount)] +#[account] pub struct ObservationState { - /// Whether the ObservationState is initialized + pub compression_info: Option, pub initialized: bool, - /// the most-recently updated index of the observations array pub observation_index: u16, pub pool_id: Pubkey, - /// observation array pub observations: [Observation; OBSERVATION_NUM], - /// padding for feature update pub padding: [u64; 4], } -impl Default for ObservationState { - #[inline] - fn default() -> ObservationState { - ObservationState { - initialized: false, - observation_index: 0, - pool_id: Pubkey::default(), - observations: [Observation::default(); OBSERVATION_NUM], - padding: [0u64; 4], - } - } -} - impl ObservationState { - pub const LEN: usize = 8 + 1 + 2 + 32 + (Observation::LEN * OBSERVATION_NUM) + 8 * 4; - - // Writes an oracle observation to the account, returning the next observation_index. - /// Writable at most once per second. Index represents the most recently written element. - /// If the index is at the end of the allowable array length (100 - 1), the next index will turn to 0. - /// - /// # Arguments - /// - /// * `self` - The ObservationState account to write in - /// * `block_timestamp` - The current timestamp of to update - /// * `token_0_price_x32` - The token_0_price_x32 at the time of the new observation - /// * `token_1_price_x32` - The token_1_price_x32 at the time of the new observation - /// * `observation_index` - The last update index of element in the oracle array - /// - /// # Return - /// * `next_observation_index` - The new index of element to update in the oracle array - /// pub fn update( &mut self, block_timestamp: u64, @@ -78,8 +35,8 @@ impl ObservationState { token_1_price_x32: u128, ) { let observation_index = self.observation_index; + if !self.initialized { - // skip the pool init price self.initialized = true; self.observations[observation_index as usize].block_timestamp = block_timestamp; self.observations[observation_index as usize].cumulative_token_0_price_x32 = 0; @@ -98,7 +55,6 @@ impl ObservationState { observation_index + 1 }; self.observations[next_observation_index as usize].block_timestamp = block_timestamp; - // cumulative_token_price_x32 only occupies the first 64 bits, and the remaining 64 bits are used to store overflow data self.observations[next_observation_index as usize].cumulative_token_0_price_x32 = last_observation .cumulative_token_0_price_x32 @@ -112,10 +68,8 @@ impl ObservationState { } } -/// Returns the block timestamp truncated to 32 bits, i.e. mod 2**32 -/// pub fn block_timestamp() -> u64 { - Clock::get().unwrap().unix_timestamp as u64 // truncation is desired + Clock::get().unwrap().unix_timestamp as u64 } #[cfg(test)] @@ -125,16 +79,3 @@ pub fn block_timestamp_mock() -> u64 { .unwrap() .as_secs() } - -#[cfg(test)] -pub mod observation_test { - use super::*; - - #[test] - fn observation_state_size_test() { - assert_eq!( - std::mem::size_of::(), - ObservationState::LEN - 8 - ) - } -} diff --git a/programs/cp-swap/src/states/pool.rs b/programs/cp-swap/src/states/pool.rs index c80606c..b23db7b 100644 --- a/programs/cp-swap/src/states/pool.rs +++ b/programs/cp-swap/src/states/pool.rs @@ -1,12 +1,14 @@ use anchor_lang::prelude::*; -use anchor_spl::token_interface::Mint; +use light_anchor_spl::token_interface::Mint; +use light_sdk::LightDiscriminator; +use light_token::anchor::{CompressionInfo, LightAccount}; use std::ops::{BitAnd, BitOr, BitXor}; -/// Seed to derive account address and signature + pub const POOL_SEED: &str = "pool"; pub const POOL_LP_MINT_SEED: &str = "pool_lp_mint"; pub const POOL_VAULT_SEED: &str = "pool_vault"; -pub const Q32: u128 = (u32::MAX as u128) + 1; // 2^32 +pub const Q32: u128 = (u32::MAX as u128) + 1; pub enum PoolStatusBitIndex { Deposit, @@ -20,67 +22,37 @@ pub enum PoolStatusBitFlag { Disable, } -#[account(zero_copy(unsafe))] -#[repr(C, packed)] -#[derive(Default, Debug)] +#[derive(Default, Debug, InitSpace, LightAccount)] +#[account] +#[repr(C)] pub struct PoolState { - /// Which config the pool belongs + pub compression_info: Option, pub amm_config: Pubkey, - /// pool creator pub pool_creator: Pubkey, - /// Token A pub token_0_vault: Pubkey, - /// Token B pub token_1_vault: Pubkey, - - /// Pool tokens are issued when A or B tokens are deposited. - /// Pool tokens can be withdrawn back to the original A or B token. pub lp_mint: Pubkey, - /// Mint information for token A pub token_0_mint: Pubkey, - /// Mint information for token B pub token_1_mint: Pubkey, - - /// token_0 program pub token_0_program: Pubkey, - /// token_1 program pub token_1_program: Pubkey, - - /// observation account to store oracle data pub observation_key: Pubkey, - pub auth_bump: u8, - /// Bitwise representation of the state of the pool - /// bit0, 1: disable deposit(value is 1), 0: normal - /// bit1, 1: disable withdraw(value is 2), 0: normal - /// bit2, 1: disable swap(value is 4), 0: normal pub status: u8, - pub lp_mint_decimals: u8, - /// mint0 and mint1 decimals pub mint_0_decimals: u8, pub mint_1_decimals: u8, - - /// True circulating supply without burns and lock ups pub lp_supply: u64, - /// The amounts of token_0 and token_1 that are owed to the liquidity provider. pub protocol_fees_token_0: u64, pub protocol_fees_token_1: u64, - pub fund_fees_token_0: u64, pub fund_fees_token_1: u64, - - /// The timestamp allowed for swap in the pool. pub open_time: u64, - /// recent epoch pub recent_epoch: u64, - /// padding for future updates - pub padding: [u64; 31], + pub padding: [u64; 1], } impl PoolState { - pub const LEN: usize = 8 + 10 * 32 + 1 * 5 + 8 * 7 + 8 * 31; - pub fn initialize( &mut self, auth_bump: u8, @@ -92,7 +64,7 @@ impl PoolState { token_1_vault: Pubkey, token_0_mint: &InterfaceAccount, token_1_mint: &InterfaceAccount, - lp_mint: &InterfaceAccount, + lp_mint: &AccountInfo, observation_key: Pubkey, ) { self.amm_config = amm_config.key(); @@ -106,7 +78,7 @@ impl PoolState { self.token_1_program = *token_1_mint.to_account_info().owner; self.observation_key = observation_key; self.auth_bump = auth_bump; - self.lp_mint_decimals = lp_mint.decimals; + self.lp_mint_decimals = 9; self.mint_0_decimals = token_0_mint.decimals; self.mint_1_decimals = token_1_mint.decimals; self.lp_supply = lp_supply; @@ -116,11 +88,11 @@ impl PoolState { self.fund_fees_token_1 = 0; self.open_time = open_time; self.recent_epoch = Clock::get().unwrap().epoch; - self.padding = [0u64; 31]; + self.padding = [0u64; 1]; } pub fn set_status(&mut self, status: u8) { - self.status = status + self.status = status; } pub fn set_status_by_bit(&mut self, bit: PoolStatusBitIndex, flag: PoolStatusBitFlag) { @@ -133,7 +105,6 @@ impl PoolState { } } - /// Get status by bit, if it is `noraml` status, return true pub fn get_status_by_bit(&self, bit: PoolStatusBitIndex) -> bool { let status = u8::from(1) << (bit as u8); self.status.bitand(status) == 0 @@ -163,18 +134,13 @@ impl PoolState { pub mod pool_test { use super::*; - #[test] - fn pool_state_size_test() { - assert_eq!(std::mem::size_of::(), PoolState::LEN - 8) - } - mod pool_status_test { use super::*; #[test] fn get_set_status_by_bit() { let mut pool_state = PoolState::default(); - pool_state.set_status(4); // 0000100 + pool_state.set_status(4); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), false @@ -188,28 +154,24 @@ pub mod pool_test { true ); - // disable -> disable, nothing to change pool_state.set_status_by_bit(PoolStatusBitIndex::Swap, PoolStatusBitFlag::Disable); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), false ); - // disable -> enable pool_state.set_status_by_bit(PoolStatusBitIndex::Swap, PoolStatusBitFlag::Enable); assert_eq!(pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), true); - // enable -> enable, nothing to change pool_state.set_status_by_bit(PoolStatusBitIndex::Swap, PoolStatusBitFlag::Enable); assert_eq!(pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), true); - // enable -> disable pool_state.set_status_by_bit(PoolStatusBitIndex::Swap, PoolStatusBitFlag::Disable); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), false ); - pool_state.set_status(5); // 0000101 + pool_state.set_status(5); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), false @@ -223,7 +185,7 @@ pub mod pool_test { true ); - pool_state.set_status(7); // 0000111 + pool_state.set_status(7); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), false @@ -237,7 +199,7 @@ pub mod pool_test { false ); - pool_state.set_status(3); // 0000011 + pool_state.set_status(3); assert_eq!(pool_state.get_status_by_bit(PoolStatusBitIndex::Swap), true); assert_eq!( pool_state.get_status_by_bit(PoolStatusBitIndex::Deposit), diff --git a/programs/cp-swap/src/utils/account_load.rs b/programs/cp-swap/src/utils/account_load.rs deleted file mode 100644 index e215750..0000000 --- a/programs/cp-swap/src/utils/account_load.rs +++ /dev/null @@ -1,169 +0,0 @@ -use anchor_lang::{ - error::{Error, ErrorCode}, - solana_program::{account_info::AccountInfo, pubkey::Pubkey}, - Key, Owner, Result, ToAccountInfos, ZeroCopy, -}; -use arrayref::array_ref; -use std::cell::{Ref, RefMut}; -use std::marker::PhantomData; -use std::mem; -use std::ops::DerefMut; - -#[derive(Clone)] -pub struct AccountLoad<'info, T: ZeroCopy + Owner> { - acc_info: AccountInfo<'info>, - phantom: PhantomData<&'info T>, -} - -impl<'info, T: ZeroCopy + Owner> AccountLoad<'info, T> { - fn new(acc_info: AccountInfo<'info>) -> AccountLoad<'info, T> { - Self { - acc_info, - phantom: PhantomData, - } - } - - /// Constructs a new `Loader` from a previously initialized account. - #[inline(never)] - pub fn try_from(acc_info: &AccountInfo<'info>) -> Result> { - if acc_info.owner != &T::owner() { - return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram) - .with_pubkeys((*acc_info.owner, T::owner()))); - } - let data: &[u8] = &acc_info.try_borrow_data()?; - if data.len() < T::DISCRIMINATOR.len() { - return Err(ErrorCode::AccountDiscriminatorNotFound.into()); - } - // Discriminator must match. - let disc_bytes = array_ref![data, 0, 8]; - if disc_bytes != &T::DISCRIMINATOR { - return Err(ErrorCode::AccountDiscriminatorMismatch.into()); - } - - Ok(AccountLoad::new(acc_info.clone())) - } - - /// Constructs a new `Loader` from an uninitialized account. - #[inline(never)] - pub fn try_from_unchecked( - _program_id: &Pubkey, - acc_info: &AccountInfo<'info>, - ) -> Result> { - if acc_info.owner != &T::owner() { - return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram) - .with_pubkeys((*acc_info.owner, T::owner()))); - } - Ok(AccountLoad::new(acc_info.clone())) - } - - /// Returns a `RefMut` to the account data structure for reading or writing. - /// Should only be called once, when the account is being initialized. - pub fn load_init(&self) -> Result> { - // AccountInfo api allows you to borrow mut even if the account isn't - // writable, so add this check for a better dev experience. - if !self.acc_info.is_writable { - return Err(ErrorCode::AccountNotMutable.into()); - } - - let mut data = self.acc_info.try_borrow_mut_data()?; - - // The discriminator should be zero, since we're initializing. - let mut disc_bytes = [0u8; 8]; - disc_bytes.copy_from_slice(&data[..8]); - let discriminator = u64::from_le_bytes(disc_bytes); - if discriminator != 0 { - return Err(ErrorCode::AccountDiscriminatorAlreadySet.into()); - } - - // write discriminator - data[..8].copy_from_slice(&T::DISCRIMINATOR); - - Ok(RefMut::map(data, |data| { - bytemuck::from_bytes_mut(&mut data.deref_mut()[8..mem::size_of::() + 8]) - })) - } - - /// Returns a `RefMut` to the account data structure for reading or writing directly. - /// There is no need to convert AccountInfo to AccountLoad. - /// So it is necessary to check the owner - pub fn load_data_mut<'a>(acc_info: &'a AccountInfo) -> Result> { - if acc_info.owner != &T::owner() { - return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram) - .with_pubkeys((*acc_info.owner, T::owner()))); - } - if !acc_info.is_writable { - return Err(ErrorCode::AccountNotMutable.into()); - } - - let data = acc_info.try_borrow_mut_data()?; - if data.len() < T::DISCRIMINATOR.len() { - return Err(ErrorCode::AccountDiscriminatorNotFound.into()); - } - - let disc_bytes = array_ref![data, 0, 8]; - if disc_bytes != &T::DISCRIMINATOR { - return Err(ErrorCode::AccountDiscriminatorMismatch.into()); - } - - Ok(RefMut::map(data, |data| { - bytemuck::from_bytes_mut(&mut data.deref_mut()[8..mem::size_of::() + 8]) - })) - } - - /// Returns a Ref to the account data structure for reading. - pub fn load(&self) -> Result> { - let data = self.acc_info.try_borrow_data()?; - if data.len() < T::DISCRIMINATOR.len() { - return Err(ErrorCode::AccountDiscriminatorNotFound.into()); - } - - let disc_bytes = array_ref![data, 0, 8]; - if disc_bytes != &T::DISCRIMINATOR { - return Err(ErrorCode::AccountDiscriminatorMismatch.into()); - } - - Ok(Ref::map(data, |data| { - bytemuck::from_bytes(&data[8..mem::size_of::() + 8]) - })) - } - - /// Returns a `RefMut` to the account data structure for reading or writing. - pub fn load_mut(&self) -> Result> { - // AccountInfo api allows you to borrow mut even if the account isn't - // writable, so add this check for a better dev experience. - if !self.acc_info.is_writable { - return Err(ErrorCode::AccountNotMutable.into()); - } - - let data = self.acc_info.try_borrow_mut_data()?; - if data.len() < T::DISCRIMINATOR.len() { - return Err(ErrorCode::AccountDiscriminatorNotFound.into()); - } - - let disc_bytes = array_ref![data, 0, 8]; - if disc_bytes != &T::DISCRIMINATOR { - return Err(ErrorCode::AccountDiscriminatorMismatch.into()); - } - - Ok(RefMut::map(data, |data| { - bytemuck::from_bytes_mut(&mut data.deref_mut()[8..mem::size_of::() + 8]) - })) - } -} - -impl<'info, T: ZeroCopy + Owner> AsRef> for AccountLoad<'info, T> { - fn as_ref(&self) -> &AccountInfo<'info> { - &self.acc_info - } -} -impl<'info, T: ZeroCopy + Owner> ToAccountInfos<'info> for AccountLoad<'info, T> { - fn to_account_infos(&self) -> Vec> { - vec![self.acc_info.clone()] - } -} - -impl<'info, T: ZeroCopy + Owner> Key for AccountLoad<'info, T> { - fn key(&self) -> Pubkey { - *self.acc_info.key - } -} diff --git a/programs/cp-swap/src/utils/mod.rs b/programs/cp-swap/src/utils/mod.rs index 43cda1c..6d161ff 100644 --- a/programs/cp-swap/src/utils/mod.rs +++ b/programs/cp-swap/src/utils/mod.rs @@ -1,7 +1,5 @@ -pub mod account_load; pub mod math; pub mod token; -pub use account_load::*; pub use math::*; pub use token::*; diff --git a/programs/cp-swap/src/utils/token.rs b/programs/cp-swap/src/utils/token.rs index e40ba75..1849b79 100644 --- a/programs/cp-swap/src/utils/token.rs +++ b/programs/cp-swap/src/utils/token.rs @@ -1,10 +1,12 @@ use crate::error::ErrorCode; use anchor_lang::{prelude::*, system_program}; -use anchor_spl::{ +use light_anchor_spl::{ token::{Token, TokenAccount}, token_2022, token_interface::{initialize_account3, InitializeAccount3, Mint}, }; +use light_sdk::constants::LIGHT_TOKEN_PROGRAM_ID; +use light_token::instruction::TransferInterfaceCpi; use spl_token_2022::{ self, extension::{ @@ -14,6 +16,33 @@ use spl_token_2022::{ }; use std::collections::HashSet; +/// SPL Token mint size (first 82 bytes are SPL-compatible for light tokens) +const SPL_MINT_SIZE: usize = 82; +/// Account type byte position (byte 165) +const ACCOUNT_TYPE_OFFSET: usize = 165; +/// Account type discriminator for Mint +const ACCOUNT_TYPE_MINT: u8 = 1; + +/// Extract decimals from mint data, supporting both SPL and Light token mints. +/// For extended mints (>82 bytes), validates byte 165 == 1 (Mint type). +fn get_mint_decimals(mint_data: &[u8]) -> Result { + // For extended mints, verify account type is Mint (byte 165 == 1) + if mint_data.len() > ACCOUNT_TYPE_OFFSET { + if mint_data[ACCOUNT_TYPE_OFFSET] != ACCOUNT_TYPE_MINT { + return err!(ErrorCode::InvalidAccountData); + } + } + + // Use first 82 bytes for SPL compatibility + let mint_slice = if mint_data.len() > SPL_MINT_SIZE { + &mint_data[..SPL_MINT_SIZE] + } else { + mint_data + }; + let mint_state = StateWithExtensions::::unpack(mint_slice)?; + Ok(mint_state.base.decimals) +} + const MINT_WHITELIST: [&'static str; 4] = [ "HVbpJAQGNpkgBaYBZQBR1t7yFdvaYVp2vCQQfKKEN4tM", "Crn4x1Y2HUKko7ox2EZMT6N2t2ZyH7eKtwkBGVnhEq1g", @@ -26,26 +55,34 @@ pub fn transfer_from_user_to_pool_vault<'a>( from: AccountInfo<'a>, to_vault: AccountInfo<'a>, mint: AccountInfo<'a>, - token_program: AccountInfo<'a>, + _token_program: AccountInfo<'a>, amount: u64, - mint_decimals: u8, + payer: AccountInfo<'a>, + light_token_cpi_authority: AccountInfo<'a>, + system_program: AccountInfo<'a>, ) -> Result<()> { if amount == 0 { return Ok(()); } - token_2022::transfer_checked( - CpiContext::new( - token_program.to_account_info(), - token_2022::TransferChecked { - from, - to: to_vault, - authority, - mint, - }, - ), + + let mint_data = mint.try_borrow_data()?; + let decimals = get_mint_decimals(&mint_data)?; + drop(mint_data); + + TransferInterfaceCpi::new( amount, - mint_decimals, + decimals, + from, + to_vault, + authority, + payer, + light_token_cpi_authority, + system_program, ) + .invoke() + .map_err(|e| anchor_lang::prelude::ProgramError::from(e))?; + + Ok(()) } pub fn transfer_from_pool_vault_to_user<'a>( @@ -53,80 +90,45 @@ pub fn transfer_from_pool_vault_to_user<'a>( from_vault: AccountInfo<'a>, to: AccountInfo<'a>, mint: AccountInfo<'a>, - token_program: AccountInfo<'a>, + _token_program: AccountInfo<'a>, amount: u64, - mint_decimals: u8, signer_seeds: &[&[&[u8]]], + payer: AccountInfo<'a>, + light_token_cpi_authority: AccountInfo<'a>, + system_program: AccountInfo<'a>, ) -> Result<()> { if amount == 0 { return Ok(()); } - token_2022::transfer_checked( - CpiContext::new_with_signer( - token_program.to_account_info(), - token_2022::TransferChecked { - from: from_vault, - to, - authority, - mint, - }, - signer_seeds, - ), - amount, - mint_decimals, - ) -} -/// Issue a spl_token `MintTo` instruction. -pub fn token_mint_to<'a>( - authority: AccountInfo<'a>, - token_program: AccountInfo<'a>, - mint: AccountInfo<'a>, - destination: AccountInfo<'a>, - amount: u64, - signer_seeds: &[&[&[u8]]], -) -> Result<()> { - token_2022::mint_to( - CpiContext::new_with_signer( - token_program, - token_2022::MintTo { - to: destination, - authority, - mint, - }, - signer_seeds, - ), - amount, - ) -} + let mint_data = mint.try_borrow_data()?; + let decimals = get_mint_decimals(&mint_data)?; + drop(mint_data); -pub fn token_burn<'a>( - authority: AccountInfo<'a>, - token_program: AccountInfo<'a>, - mint: AccountInfo<'a>, - from: AccountInfo<'a>, - amount: u64, - signer_seeds: &[&[&[u8]]], -) -> Result<()> { - token_2022::burn( - CpiContext::new_with_signer( - token_program.to_account_info(), - token_2022::Burn { - from, - authority, - mint, - }, - signer_seeds, - ), + TransferInterfaceCpi::new( amount, + decimals, + from_vault, + to, + authority, + payer, + light_token_cpi_authority, + system_program, ) + .invoke_signed(signer_seeds) + .map_err(|e| anchor_lang::prelude::ProgramError::from(e))?; + + Ok(()) } -/// Calculate the fee for output amount pub fn get_transfer_inverse_fee(mint_info: &AccountInfo, post_fee_amount: u64) -> Result { if *mint_info.owner == Token::id() { return Ok(0); } + // Light token mints don't have transfer fees + if *mint_info.owner == Pubkey::from(LIGHT_TOKEN_PROGRAM_ID) { + return Ok(0); + } if post_fee_amount == 0 { return err!(ErrorCode::InvalidInput); } @@ -157,11 +159,14 @@ pub fn get_transfer_inverse_fee(mint_info: &AccountInfo, post_fee_amount: u64) - Ok(fee) } -/// Calculate the fee for input amount pub fn get_transfer_fee(mint_info: &AccountInfo, pre_fee_amount: u64) -> Result { if *mint_info.owner == Token::id() { return Ok(0); } + // Light token mints don't have transfer fees + if *mint_info.owner == Pubkey::from(LIGHT_TOKEN_PROGRAM_ID) { + return Ok(0); + } let mint_data = mint_info.try_borrow_data()?; let mint = StateWithExtensions::::unpack(&mint_data)?; @@ -180,6 +185,10 @@ pub fn is_supported_mint(mint_account: &InterfaceAccount) -> Result if *mint_info.owner == Token::id() { return Ok(true); } + // Support light token mints + if *mint_info.owner == Pubkey::from(LIGHT_TOKEN_PROGRAM_ID) { + return Ok(true); + } let mint_whitelist: HashSet<&str> = MINT_WHITELIST.into_iter().collect(); if mint_whitelist.contains(mint_account.key().to_string().as_str()) { return Ok(true); @@ -188,12 +197,7 @@ pub fn is_supported_mint(mint_account: &InterfaceAccount) -> Result let mint = StateWithExtensions::::unpack(&mint_data)?; let extensions = mint.get_extension_types()?; for e in extensions { - if e != ExtensionType::TransferFeeConfig - && e != ExtensionType::MetadataPointer - && e != ExtensionType::TokenMetadata - && e != ExtensionType::InterestBearingConfig - && e != ExtensionType::ScaledUiAmount - { + if e != ExtensionType::TokenMetadata { return Ok(false); } } @@ -248,7 +252,7 @@ pub fn create_or_allocate_account<'a>( payer: AccountInfo<'a>, system_program: AccountInfo<'a>, target_account: AccountInfo<'a>, - siger_seed: &[&[u8]], + signer_seed: &[&[u8]], space: usize, ) -> Result<()> { let rent = Rent::get()?; @@ -262,7 +266,7 @@ pub fn create_or_allocate_account<'a>( }; let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts); system_program::create_account( - cpi_context.with_signer(&[siger_seed]), + cpi_context.with_signer(&[signer_seed]), lamports, u64::try_from(space).unwrap(), program_id, @@ -285,7 +289,7 @@ pub fn create_or_allocate_account<'a>( }; let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts); system_program::allocate( - cpi_context.with_signer(&[siger_seed]), + cpi_context.with_signer(&[signer_seed]), u64::try_from(space).unwrap(), )?; @@ -293,7 +297,7 @@ pub fn create_or_allocate_account<'a>( account_to_assign: target_account.clone(), }; let cpi_context = CpiContext::new(system_program.clone(), cpi_accounts); - system_program::assign(cpi_context.with_signer(&[siger_seed]), program_id)?; + system_program::assign(cpi_context.with_signer(&[signer_seed]), program_id)?; } Ok(()) } diff --git a/programs/cp-swap/tests/functional_test.rs b/programs/cp-swap/tests/functional_test.rs new file mode 100644 index 0000000..9b6218c --- /dev/null +++ b/programs/cp-swap/tests/functional_test.rs @@ -0,0 +1,285 @@ +/// Functional integration test for cp-swap program. +/// Tests pool initialization with light-program-test framework. + +use light_client::interface::AccountInterfaceExt; +use light_program_test::program_test::TestRpc; +use light_program_test::Rpc; +use solana_keypair::Keypair; +use solana_signer::Signer; + +mod helpers; +mod program; +use helpers::*; + +#[tokio::test] +async fn test_full_lifecycle() { + let program_id = raydium_cp_swap::ID; + + // ======================================================================== + // Setup + // ======================================================================== + let mut env = setup_test_environment(program_id).await; + + // Create and fund creator with more lamports for multiple transactions + let creator = Keypair::new(); + env.rpc + .airdrop_lamports(&creator.pubkey(), 100_000_000_000) + .await + .unwrap(); + + // Get admin keypair and fund it + let admin = get_admin_keypair(); + env.rpc + .airdrop_lamports(&admin.pubkey(), 10_000_000_000) + .await + .unwrap(); + + // Setup token mints with larger initial balance for lifecycle operations + let initial_balance = 1_000_000; + let tokens = + setup_token_mints(&mut env.rpc, &env.payer, &creator.pubkey(), initial_balance).await; + + // Create AMM config (use index 1 to avoid collision with test_initialize_pool) + let amm_config = create_amm_config(&mut env.rpc, &env.payer, &admin, program_id, 1).await; + assert_amm_config_created(&mut env.rpc, amm_config).await; + + // Setup create pool fee account + setup_create_pool_fee_account(&mut env.rpc, &env.payer.pubkey()); + + // Derive PDAs + let pdas = derive_amm_pdas( + &program_id, + &amm_config, + &tokens.token_0_mint, + &tokens.token_1_mint, + &creator.pubkey(), + ); + + // ======================================================================== + // Initialize Pool + // ======================================================================== + let proof_result = get_pool_create_accounts_proof(&env.rpc, &program_id, &pdas).await; + + let init_amount_0 = 100_000; + let init_amount_1 = 100_000; + + let init_instruction = build_initialize_instruction( + program_id, + creator.pubkey(), + amm_config, + &pdas, + &tokens, + env.config_pda, + &proof_result, + init_amount_0, + init_amount_1, + 0, // open_time = 0 (immediate) + ); + + env.rpc + .create_and_send_transaction(&[init_instruction], &creator.pubkey(), &[&creator]) + .await + .expect("Initialize should succeed"); + + assert_pool_initialized(&mut env.rpc, &pdas).await; + + // Check initial LP token balance (should have received initial LP tokens from initialize) + let lp_balance_after_init = get_token_balance(&mut env.rpc, pdas.creator_lp_token).await; + println!("LP balance after init: {}", lp_balance_after_init); + assert!(lp_balance_after_init > 0, "Should have received LP tokens from initialization"); + + // ======================================================================== + // Deposit + // ======================================================================== + let lp_balance_before_deposit = get_token_balance(&mut env.rpc, pdas.creator_lp_token).await; + + // Deposit: request LP tokens, allow 10% slippage on tokens provided + let deposit_lp_amount = 500; + let max_token_0 = 10_000; // Allow generous slippage + let max_token_1 = 10_000; + + let deposit_instruction = build_deposit_instruction( + program_id, + creator.pubkey(), + &pdas, + &tokens, + tokens.creator_token_0, + tokens.creator_token_1, + deposit_lp_amount, + max_token_0, + max_token_1, + ); + + env.rpc + .create_and_send_transaction(&[deposit_instruction], &creator.pubkey(), &[&creator]) + .await + .expect("Deposit should succeed"); + + assert_deposit_succeeded( + &mut env.rpc, + pdas.creator_lp_token, + lp_balance_before_deposit, + deposit_lp_amount, + ) + .await; + + println!( + "Deposit succeeded. LP balance: {}", + get_token_balance(&mut env.rpc, pdas.creator_lp_token).await + ); + + // ======================================================================== + // Swap (token_0 -> token_1) + // ======================================================================== + // Warp time forward so pool is open for swaps (open_time = block_timestamp + 1) + env.rpc.warp_to_slot(100).unwrap(); + + let token_0_balance_before = get_token_balance(&mut env.rpc, tokens.creator_token_0).await; + let token_1_balance_before = get_token_balance(&mut env.rpc, tokens.creator_token_1).await; + + // Swap: 100 token_0 for token_1, allow 50% slippage + let swap_amount_in = 100; + let min_amount_out = 1; // Allow high slippage for test stability + + let swap_instruction = build_swap_instruction( + program_id, + creator.pubkey(), + amm_config, + &pdas, + &tokens, + tokens.creator_token_0, // input + tokens.creator_token_1, // output + true, // is_token_0_input + swap_amount_in, + min_amount_out, + ); + + env.rpc + .create_and_send_transaction(&[swap_instruction], &creator.pubkey(), &[&creator]) + .await + .expect("Swap should succeed"); + + assert_swap_succeeded( + &mut env.rpc, + tokens.creator_token_0, + tokens.creator_token_1, + token_0_balance_before, + token_1_balance_before, + swap_amount_in, + min_amount_out, + ) + .await; + + println!( + "Swap succeeded. Token 0 balance: {}, Token 1 balance: {}", + get_token_balance(&mut env.rpc, tokens.creator_token_0).await, + get_token_balance(&mut env.rpc, tokens.creator_token_1).await + ); + + // ======================================================================== + // Withdraw (burn half of LP tokens) + // ======================================================================== + let lp_balance_before_withdraw = get_token_balance(&mut env.rpc, pdas.creator_lp_token).await; + let withdraw_lp_amount = lp_balance_before_withdraw / 2; + + // Allow any amount of tokens out (0 minimum) + let withdraw_instruction = build_withdraw_instruction( + program_id, + creator.pubkey(), + &pdas, + &tokens, + tokens.creator_token_0, + tokens.creator_token_1, + withdraw_lp_amount, + 0, // minimum_token_0_amount - accept any + 0, // minimum_token_1_amount - accept any + ); + + env.rpc + .create_and_send_transaction(&[withdraw_instruction], &creator.pubkey(), &[&creator]) + .await + .expect("Withdraw should succeed"); + + assert_withdraw_succeeded( + &mut env.rpc, + pdas.creator_lp_token, + lp_balance_before_withdraw, + withdraw_lp_amount, + ) + .await; + + println!( + "Withdraw succeeded. LP balance: {}, Token 0 balance: {}, Token 1 balance: {}", + get_token_balance(&mut env.rpc, pdas.creator_lp_token).await, + get_token_balance(&mut env.rpc, tokens.creator_token_0).await, + get_token_balance(&mut env.rpc, tokens.creator_token_1).await + ); + + println!("Full lifecycle test completed successfully!"); +} + +/// Test SDK initialization from fetched accounts and account requirements. +#[tokio::test] +async fn test_sdk_from_keyed_accounts() { + use program::{CpSwapSdk, CpSwapInstruction}; + use light_client::interface::LightProgramInterface; + + let program_id = raydium_cp_swap::ID; + + // Setup environment and initialize pool + let mut setup = setup_pool_environment(program_id, 2).await; + + // Initialize pool first (SDK requires actual account data) + let proof_result = get_pool_create_accounts_proof(&setup.env.rpc, &program_id, &setup.pdas).await; + let init_ix = build_initialize_instruction( + program_id, + setup.creator.pubkey(), + setup.amm_config, + &setup.pdas, + &setup.tokens, + setup.env.config_pda, + &proof_result, + 100_000, + 100_000, + 0, + ); + setup.env.rpc + .create_and_send_transaction(&[init_ix], &setup.creator.pubkey(), &[&setup.creator]) + .await + .expect("Initialize should succeed"); + + // Fetch pool state account + let pool_interface = setup.env.rpc + .get_account_interface(&setup.pdas.pool_state, &program_id) + .await + .expect("get_account_interface should succeed"); + + // Create SDK from fetched account + let sdk = CpSwapSdk::from_keyed_accounts(&[pool_interface]) + .expect("from_keyed_accounts should succeed"); + + // Verify SDK parsed addresses match expected + assert_eq!(sdk.pool_state_pubkey, Some(setup.pdas.pool_state)); + assert_eq!(sdk.observation_key, Some(setup.pdas.observation_state)); + assert_eq!(sdk.token_0_vault, Some(setup.pdas.token_0_vault)); + assert_eq!(sdk.token_1_vault, Some(setup.pdas.token_1_vault)); + assert_eq!(sdk.lp_mint, Some(setup.pdas.lp_mint)); + assert_eq!(sdk.amm_config, Some(setup.amm_config)); + assert_eq!(sdk.token_0_mint, Some(setup.tokens.token_0_mint)); + assert_eq!(sdk.token_1_mint, Some(setup.tokens.token_1_mint)); + + // Check account requirements for each instruction type + let swap_accounts = sdk.get_accounts_to_update(&CpSwapInstruction::Swap); + assert_eq!(swap_accounts.len(), 6, "Swap needs 6 accounts: pool, observation, vault0, vault1, mint0, mint1"); + + let deposit_accounts = sdk.get_accounts_to_update(&CpSwapInstruction::Deposit); + assert_eq!(deposit_accounts.len(), 7, "Deposit needs 7 accounts: pool, observation, vault0, vault1, lp_mint, mint0, mint1"); + + let withdraw_accounts = sdk.get_accounts_to_update(&CpSwapInstruction::Withdraw); + assert_eq!(withdraw_accounts.len(), 7, "Withdraw needs 7 accounts: pool, observation, vault0, vault1, lp_mint, mint0, mint1"); + + // Verify program_id method + assert_eq!(sdk.program_id(), program_id); + + println!("SDK initialization test completed successfully!"); +} diff --git a/programs/cp-swap/tests/helpers.rs b/programs/cp-swap/tests/helpers.rs new file mode 100644 index 0000000..b0e4b32 --- /dev/null +++ b/programs/cp-swap/tests/helpers.rs @@ -0,0 +1,857 @@ +#![allow(dead_code)] + +/// Functional integration test for cp-swap program. +/// Tests pool initialization with light-program-test framework. + +use anchor_lang::{InstructionData, ToAccountMetas}; +use light_client::interface::{ + get_create_accounts_proof, CreateAccountsProofInput, CreateAccountsProofResult, + InitializeRentFreeConfig, +}; +use solana_pubkey::pubkey; +use light_program_test::{ + program_test::{setup_mock_program_data, LightProgramTest, TestRpc}, + Indexer, ProgramTestConfig, Rpc, +}; +use light_token::{ + constants::CPI_AUTHORITY_PDA, + instruction::{ + find_mint_address, get_associated_token_address_and_bump, CreateAssociatedTokenAccount, + CreateMint, CreateMintParams, MintTo, COMPRESSIBLE_CONFIG_V1, + RENT_SPONSOR as LIGHT_TOKEN_RENT_SPONSOR, + }, + constants::LIGHT_TOKEN_PROGRAM_ID, +}; +use raydium_cp_swap::{ + instructions::initialize::LP_MINT_SIGNER_SEED, + states::{AMM_CONFIG_SEED, OBSERVATION_SEED, POOL_SEED, POOL_VAULT_SEED}, + InitializeParams, AUTH_SEED, +}; +use solana_instruction::Instruction; +use solana_keypair::Keypair; +use solana_pubkey::Pubkey; +use solana_signer::Signer; +use solana_sdk::{program_pack::Pack, signature::SeedDerivable}; +use light_anchor_spl::memo::spl_memo; +use spl_token_2022; + + + +// ============================================================================ +// Constants +// ============================================================================ + +const RENT_SPONSOR: Pubkey = pubkey!("CLEuMG7pzJX9xAuKCFzBP154uiG1GaNo4Fq7x6KAcAfG"); + +pub fn light_token_program_id() -> Pubkey { + Pubkey::from(LIGHT_TOKEN_PROGRAM_ID) +} + +// ============================================================================ +// Types +// ============================================================================ +/// PDAs for the AMM pool. +pub struct AmmPdas { + pub pool_state: Pubkey, + pub observation_state: Pubkey, + pub authority: Pubkey, + pub authority_bump: u8, + pub token_0_vault: Pubkey, + pub token_1_vault: Pubkey, + pub lp_mint_signer: Pubkey, + pub lp_mint_signer_bump: u8, + pub lp_mint: Pubkey, + pub creator_lp_token: Pubkey, + pub creator_lp_token_bump: u8, +} + +/// Test environment setup result. +pub struct TestEnv { + pub rpc: LightProgramTest, + pub payer: Keypair, + pub config_pda: Pubkey, +} + +/// Token mints and creator accounts for the pool. +pub struct TokenSetup { + pub token_0_mint: Pubkey, + pub token_1_mint: Pubkey, + pub token_0_mint_signer: Pubkey, + pub token_1_mint_signer: Pubkey, + pub creator_token_0: Pubkey, + pub creator_token_1: Pubkey, +} + +// ============================================================================ +// Setup Functions +// ============================================================================ + +/// Initialize the test environment with LightProgramTest and compression config. +pub async fn setup_test_environment(program_id: Pubkey) -> TestEnv { + let mut config = + ProgramTestConfig::new_v2(true, Some(vec![("raydium_cp_swap", program_id)])); + config = config.with_light_protocol_events(); + + let mut rpc = LightProgramTest::new(config).await.unwrap(); + let payer = rpc.get_payer().insecure_clone(); + + let program_data_pda = setup_mock_program_data(&mut rpc, &payer, &program_id); + + let (init_config_ix, config_pda) = InitializeRentFreeConfig::new( + &program_id, + &payer.pubkey(), + &program_data_pda, + RENT_SPONSOR, + payer.pubkey(), + ) + .build(); + + rpc.create_and_send_transaction(&[init_config_ix], &payer.pubkey(), &[&payer]) + .await + .expect("Initialize config should succeed"); + + TestEnv { + rpc, + payer, + config_pda, + } +} + +/// Create a compressed mint with ATAs for recipients. +pub async fn setup_create_mint( + rpc: &mut LightProgramTest, + payer: &Keypair, + mint_authority: Pubkey, + decimals: u8, + recipients: Vec<(u64, Pubkey)>, +) -> (Pubkey, Vec, Keypair) { + let mint_seed = Keypair::new(); + let address_tree = rpc.get_address_tree_v2(); + let output_queue = rpc.get_random_state_tree_info().unwrap().queue; + + let compression_address = light_token::instruction::derive_mint_compressed_address( + &mint_seed.pubkey(), + &address_tree.tree, + ); + + let (mint, bump) = find_mint_address(&mint_seed.pubkey()); + + let rpc_result = rpc + .get_validity_proof( + vec![], + vec![light_client::indexer::AddressWithTree { + address: compression_address, + tree: address_tree.tree, + }], + None, + ) + .await + .unwrap() + .value; + + let params = CreateMintParams { + decimals, + address_merkle_tree_root_index: rpc_result.addresses[0].root_index, + mint_authority, + proof: rpc_result.proof.0.unwrap(), + compression_address, + mint, + bump, + freeze_authority: None, + extensions: None, + rent_payment: 16, + write_top_up: 766, + }; + + let create_mint_builder = CreateMint::new( + params, + mint_seed.pubkey(), + payer.pubkey(), + address_tree.tree, + output_queue, + ); + let instruction = create_mint_builder.instruction().unwrap(); + + rpc.create_and_send_transaction(&[instruction], &payer.pubkey(), &[payer, &mint_seed]) + .await + .unwrap(); + + if recipients.is_empty() { + return (mint, vec![], mint_seed); + } + + let mut ata_pubkeys = Vec::with_capacity(recipients.len()); + + for (_amount, owner) in &recipients { + let (ata_address, _bump) = get_associated_token_address_and_bump(owner, &mint); + ata_pubkeys.push(ata_address); + + let create_ata = CreateAssociatedTokenAccount::new(payer.pubkey(), *owner, mint); + let ata_instruction = create_ata.instruction().unwrap(); + + rpc.create_and_send_transaction(&[ata_instruction], &payer.pubkey(), &[payer]) + .await + .unwrap(); + } + + for (idx, (amount, _)) in recipients.iter().enumerate() { + if *amount > 0 { + let mint_instruction = MintTo { + mint, + destination: ata_pubkeys[idx], + amount: *amount, + authority: mint_authority, + max_top_up: None, + } + .instruction() + .unwrap(); + + rpc.create_and_send_transaction(&[mint_instruction], &payer.pubkey(), &[payer]) + .await + .unwrap(); + } + } + + (mint, ata_pubkeys, mint_seed) +} + +/// Create token mints and fund creator with initial balances. +pub async fn setup_token_mints( + rpc: &mut LightProgramTest, + payer: &Keypair, + creator: &Pubkey, + initial_balance: u64, +) -> TokenSetup { + let (mint_a, ata_pubkeys_a, mint_seed_a) = setup_create_mint( + rpc, + payer, + payer.pubkey(), + 9, + vec![(initial_balance, *creator)], + ) + .await; + + let (mint_b, ata_pubkeys_b, mint_seed_b) = setup_create_mint( + rpc, + payer, + payer.pubkey(), + 9, + vec![(initial_balance, *creator)], + ) + .await; + + // Ensure proper ordering: token_0_mint < token_1_mint + if mint_a < mint_b { + TokenSetup { + token_0_mint: mint_a, + token_1_mint: mint_b, + token_0_mint_signer: mint_seed_a.pubkey(), + token_1_mint_signer: mint_seed_b.pubkey(), + creator_token_0: ata_pubkeys_a[0], + creator_token_1: ata_pubkeys_b[0], + } + } else { + TokenSetup { + token_0_mint: mint_b, + token_1_mint: mint_a, + token_0_mint_signer: mint_seed_b.pubkey(), + token_1_mint_signer: mint_seed_a.pubkey(), + creator_token_0: ata_pubkeys_b[0], + creator_token_1: ata_pubkeys_a[0], + } + } +} + +// ============================================================================ +// AMM Config Functions +// ============================================================================ + +/// Create and initialize the AMM config account. +/// Get the admin keypair for testing. +/// Must match the pubkey in lib.rs admin::ID when test-sbf feature is enabled. +pub fn get_admin_keypair() -> Keypair { + // This generates pubkey: 4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS + Keypair::from_seed(&[1u8; 32]).unwrap() +} + +pub async fn create_amm_config( + rpc: &mut LightProgramTest, + payer: &Keypair, + admin: &Keypair, + program_id: Pubkey, + index: u16, +) -> Pubkey { + let (amm_config_pda, _) = Pubkey::find_program_address( + &[AMM_CONFIG_SEED.as_bytes(), &index.to_be_bytes()], + &program_id, + ); + + let create_config_accounts = raydium_cp_swap::accounts::CreateAmmConfig { + owner: admin.pubkey(), + amm_config: amm_config_pda, + system_program: solana_sdk::system_program::ID, + }; + + let create_config_data = raydium_cp_swap::instruction::CreateAmmConfig { + index, + trade_fee_rate: 2500, + protocol_fee_rate: 1000, + fund_fee_rate: 500, + create_pool_fee: 0, + }; + + let create_config_ix = Instruction { + program_id, + accounts: create_config_accounts.to_account_metas(None), + data: create_config_data.data(), + }; + + rpc.create_and_send_transaction(&[create_config_ix], &payer.pubkey(), &[payer, admin]) + .await + .expect("Create AmmConfig should succeed"); + + amm_config_pda +} + +/// Setup the create_pool_fee account (wrapped SOL token account). +pub fn setup_create_pool_fee_account(rpc: &mut LightProgramTest, owner: &Pubkey) { + let create_pool_fee_receiver = raydium_cp_swap::create_pool_fee_receiver::ID; + let wsol_mint = spl_token::native_mint::id(); + + let mut fee_receiver_data = vec![0u8; spl_token::state::Account::LEN]; + let fee_account = spl_token::state::Account { + mint: wsol_mint, + owner: *owner, + amount: 0, + delegate: solana_sdk::program_option::COption::None, + state: spl_token::state::AccountState::Initialized, + is_native: solana_sdk::program_option::COption::Some(0), + delegated_amount: 0, + close_authority: solana_sdk::program_option::COption::None, + }; + spl_token::state::Account::pack(fee_account, &mut fee_receiver_data).unwrap(); + + rpc.set_account( + create_pool_fee_receiver, + solana_sdk::account::Account { + lamports: 1_000_000_000, + data: fee_receiver_data, + owner: spl_token::id(), + executable: false, + rent_epoch: 0, + }, + ); +} + +// ============================================================================ +// PDA Derivation +// ============================================================================ + +/// Derive all AMM PDAs for the pool. +pub fn derive_amm_pdas( + program_id: &Pubkey, + amm_config: &Pubkey, + token_0_mint: &Pubkey, + token_1_mint: &Pubkey, + creator: &Pubkey, +) -> AmmPdas { + let (pool_state, _) = Pubkey::find_program_address( + &[ + POOL_SEED.as_bytes(), + amm_config.as_ref(), + token_0_mint.as_ref(), + token_1_mint.as_ref(), + ], + program_id, + ); + + let (authority, authority_bump) = + Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], program_id); + + let (observation_state, _) = Pubkey::find_program_address( + &[OBSERVATION_SEED.as_bytes(), pool_state.as_ref()], + program_id, + ); + + let (token_0_vault, _) = Pubkey::find_program_address( + &[ + POOL_VAULT_SEED.as_bytes(), + pool_state.as_ref(), + token_0_mint.as_ref(), + ], + program_id, + ); + + let (token_1_vault, _) = Pubkey::find_program_address( + &[ + POOL_VAULT_SEED.as_bytes(), + pool_state.as_ref(), + token_1_mint.as_ref(), + ], + program_id, + ); + + let (lp_mint_signer, lp_mint_signer_bump) = + Pubkey::find_program_address(&[LP_MINT_SIGNER_SEED, pool_state.as_ref()], program_id); + + let (lp_mint, _) = find_mint_address(&lp_mint_signer); + + let (creator_lp_token, creator_lp_token_bump) = + get_associated_token_address_and_bump(creator, &lp_mint); + + AmmPdas { + pool_state, + observation_state, + authority, + authority_bump, + token_0_vault, + token_1_vault, + lp_mint_signer, + lp_mint_signer_bump, + lp_mint, + creator_lp_token, + creator_lp_token_bump, + } +} + +// ============================================================================ +// Instruction Building +// ============================================================================ + +/// Get the create accounts proof for pool initialization. +pub async fn get_pool_create_accounts_proof( + rpc: &LightProgramTest, + program_id: &Pubkey, + pdas: &AmmPdas, +) -> CreateAccountsProofResult { + get_create_accounts_proof( + rpc, + program_id, + vec![ + CreateAccountsProofInput::pda(pdas.pool_state), + CreateAccountsProofInput::pda(pdas.observation_state), + CreateAccountsProofInput::mint(pdas.lp_mint_signer), + ], + ) + .await + .unwrap() +} + +/// Build the Withdraw instruction. +pub fn build_withdraw_instruction( + program_id: Pubkey, + owner: Pubkey, + pdas: &AmmPdas, + tokens: &TokenSetup, + owner_token_0: Pubkey, + owner_token_1: Pubkey, + lp_token_amount: u64, + minimum_token_0_amount: u64, + minimum_token_1_amount: u64, +) -> Instruction { + let accounts = raydium_cp_swap::accounts::Withdraw { + owner, + authority: pdas.authority, + pool_state: pdas.pool_state, + owner_lp_token: pdas.creator_lp_token, + token_0_account: owner_token_0, + token_1_account: owner_token_1, + token_0_vault: pdas.token_0_vault, + token_1_vault: pdas.token_1_vault, + token_program: spl_token::id(), + token_program_2022: spl_token_2022::id(), + vault_0_mint: tokens.token_0_mint, + vault_1_mint: tokens.token_1_mint, + lp_mint: pdas.lp_mint, + memo_program: spl_memo::id(), + system_program: solana_sdk::system_program::ID, + light_token_cpi_authority: CPI_AUTHORITY_PDA, + light_token_program: light_token_program_id(), + }; + + let instruction_data = raydium_cp_swap::instruction::Withdraw { + lp_token_amount, + minimum_token_0_amount, + minimum_token_1_amount, + }; + + Instruction { + program_id, + accounts: accounts.to_account_metas(None), + data: instruction_data.data(), + } +} + +/// Build the Swap instruction. +pub fn build_swap_instruction( + program_id: Pubkey, + payer: Pubkey, + amm_config: Pubkey, + pdas: &AmmPdas, + tokens: &TokenSetup, + input_token_account: Pubkey, + output_token_account: Pubkey, + is_token_0_input: bool, // true = swap 0->1, false = swap 1->0 + amount_in: u64, + minimum_amount_out: u64, +) -> Instruction { + let (input_vault, output_vault, input_mint, output_mint) = if is_token_0_input { + ( + pdas.token_0_vault, + pdas.token_1_vault, + tokens.token_0_mint, + tokens.token_1_mint, + ) + } else { + ( + pdas.token_1_vault, + pdas.token_0_vault, + tokens.token_1_mint, + tokens.token_0_mint, + ) + }; + + let accounts = raydium_cp_swap::accounts::Swap { + payer, + authority: pdas.authority, + amm_config, + pool_state: pdas.pool_state, + input_token_account, + output_token_account, + input_vault, + output_vault, + input_token_program: light_token_program_id(), + output_token_program: light_token_program_id(), + input_token_mint: input_mint, + output_token_mint: output_mint, + observation_state: pdas.observation_state, + light_token_program: light_token_program_id(), + system_program: solana_sdk::system_program::ID, + light_token_cpi_authority: CPI_AUTHORITY_PDA, + }; + + let instruction_data = raydium_cp_swap::instruction::SwapBaseInput { + amount_in, + minimum_amount_out, + }; + + Instruction { + program_id, + accounts: accounts.to_account_metas(None), + data: instruction_data.data(), + } +} + +/// Build the Deposit instruction. +pub fn build_deposit_instruction( + program_id: Pubkey, + owner: Pubkey, + pdas: &AmmPdas, + tokens: &TokenSetup, + owner_token_0: Pubkey, + owner_token_1: Pubkey, + lp_token_amount: u64, + maximum_token_0_amount: u64, + maximum_token_1_amount: u64, +) -> Instruction { + let accounts = raydium_cp_swap::accounts::Deposit { + owner, + authority: pdas.authority, + pool_state: pdas.pool_state, + owner_lp_token: pdas.creator_lp_token, + token_0_account: owner_token_0, + token_1_account: owner_token_1, + token_0_vault: pdas.token_0_vault, + token_1_vault: pdas.token_1_vault, + token_program: spl_token::id(), + token_program_2022: spl_token_2022::id(), + light_token_program: light_token_program_id(), + vault_0_mint: tokens.token_0_mint, + vault_1_mint: tokens.token_1_mint, + lp_mint: pdas.lp_mint, + system_program: solana_sdk::system_program::ID, + light_token_cpi_authority: CPI_AUTHORITY_PDA, + }; + + let instruction_data = raydium_cp_swap::instruction::Deposit { + lp_token_amount, + maximum_token_0_amount, + maximum_token_1_amount, + }; + + Instruction { + program_id, + accounts: accounts.to_account_metas(None), + data: instruction_data.data(), + } +} + +/// Build the Initialize instruction. +pub fn build_initialize_instruction( + program_id: Pubkey, + creator: Pubkey, + amm_config: Pubkey, + pdas: &AmmPdas, + tokens: &TokenSetup, + config_pda: Pubkey, + proof_result: &CreateAccountsProofResult, + init_amount_0: u64, + init_amount_1: u64, + open_time: u64, +) -> Instruction { + let init_params = InitializeParams { + init_amount_0, + init_amount_1, + open_time, + create_accounts_proof: proof_result.create_accounts_proof.clone(), + lp_mint_signer_bump: pdas.lp_mint_signer_bump, + creator_lp_token_bump: pdas.creator_lp_token_bump, + authority_bump: pdas.authority_bump, + }; + + let accounts = raydium_cp_swap::accounts::Initialize { + creator, + amm_config, + authority: pdas.authority, + pool_state: pdas.pool_state, + token_0_mint: tokens.token_0_mint, + token_1_mint: tokens.token_1_mint, + lp_mint_signer: pdas.lp_mint_signer, + lp_mint: pdas.lp_mint, + creator_token_0: tokens.creator_token_0, + creator_token_1: tokens.creator_token_1, + creator_lp_token: pdas.creator_lp_token, + token_0_vault: pdas.token_0_vault, + token_1_vault: pdas.token_1_vault, + observation_state: pdas.observation_state, + create_pool_fee: raydium_cp_swap::create_pool_fee_receiver::ID, + token_program: spl_token::id(), + token_0_program: light_token_program_id(), + token_1_program: light_token_program_id(), + associated_token_program: light_anchor_spl::associated_token::ID, + system_program: solana_sdk::system_program::ID, + rent: solana_sdk::sysvar::rent::ID, + compression_config: config_pda, + light_token_compressible_config: Pubkey::from(COMPRESSIBLE_CONFIG_V1), + light_token_rent_sponsor: Pubkey::from(LIGHT_TOKEN_RENT_SPONSOR), + light_token_program: light_token_program_id(), + light_token_cpi_authority: CPI_AUTHORITY_PDA, + }; + + let instruction_data = raydium_cp_swap::instruction::Initialize { + params: init_params, + }; + + Instruction { + program_id, + accounts: [ + accounts.to_account_metas(None), + proof_result.remaining_accounts.clone(), + ] + .concat(), + data: instruction_data.data(), + } +} + +// ============================================================================ +// Assertions +// ============================================================================ + +/// Get the balance of a token account. +/// Supports both SPL Token and Light Token accounts. +pub async fn get_token_balance(rpc: &mut LightProgramTest, account: Pubkey) -> u64 { + let account_data = rpc.get_account(account).await.unwrap(); + if let Some(account) = account_data { + // Token account layout: mint (32) + owner (32) + amount (8) + // Works for both SPL tokens and Light tokens + const AMOUNT_OFFSET: usize = 64; + if account.data.len() >= AMOUNT_OFFSET + 8 { + let amount_bytes = &account.data[AMOUNT_OFFSET..AMOUNT_OFFSET + 8]; + u64::from_le_bytes(amount_bytes.try_into().unwrap()) + } else { + 0 + } + } else { + 0 + } +} + +/// Assert that an account exists on-chain. +pub async fn assert_onchain_exists(rpc: &mut LightProgramTest, pda: &Pubkey) { + assert!( + rpc.get_account(*pda).await.unwrap().is_some(), + "Account {} should exist on-chain", + pda + ); +} + +/// Assert that an account is closed (doesn't exist or has 0 lamports). +pub async fn assert_onchain_closed(rpc: &mut LightProgramTest, pda: &Pubkey) { + let acc = rpc.get_account(*pda).await.unwrap(); + assert!( + acc.is_none() || acc.unwrap().lamports == 0, + "Account {} should be closed", + pda + ); +} + +/// Assert all pool accounts exist on-chain (hot or decompressed state). +pub async fn assert_pool_accounts_exist(rpc: &mut LightProgramTest, pdas: &AmmPdas, tokens: &TokenSetup) { + assert_onchain_exists(rpc, &pdas.pool_state).await; + assert_onchain_exists(rpc, &pdas.observation_state).await; + assert_onchain_exists(rpc, &pdas.lp_mint).await; + assert_onchain_exists(rpc, &pdas.token_0_vault).await; + assert_onchain_exists(rpc, &pdas.token_1_vault).await; + assert_onchain_exists(rpc, &pdas.creator_lp_token).await; + assert_onchain_exists(rpc, &tokens.token_0_mint).await; + assert_onchain_exists(rpc, &tokens.token_1_mint).await; +} + +/// Assert all pool accounts are compressed (closed on-chain). +pub async fn assert_pool_accounts_compressed(rpc: &mut LightProgramTest, pdas: &AmmPdas, tokens: &TokenSetup) { + assert_onchain_closed(rpc, &pdas.pool_state).await; + assert_onchain_closed(rpc, &pdas.observation_state).await; + assert_onchain_closed(rpc, &pdas.lp_mint).await; + assert_onchain_closed(rpc, &pdas.token_0_vault).await; + assert_onchain_closed(rpc, &pdas.token_1_vault).await; + assert_onchain_closed(rpc, &pdas.creator_lp_token).await; + assert_onchain_closed(rpc, &tokens.token_0_mint).await; + assert_onchain_closed(rpc, &tokens.token_1_mint).await; +} + +/// Verify that the pool was initialized correctly. +pub async fn assert_pool_initialized(rpc: &mut LightProgramTest, pdas: &AmmPdas) { + let pool_account = rpc.get_account(pdas.pool_state).await.unwrap(); + assert!(pool_account.is_some(), "Pool state should exist"); + + let observation_account = rpc.get_account(pdas.observation_state).await.unwrap(); + assert!( + observation_account.is_some(), + "Observation state should exist" + ); +} + +/// Assert that deposit succeeded by checking LP token balance increased. +pub async fn assert_deposit_succeeded( + rpc: &mut LightProgramTest, + owner_lp_token: Pubkey, + lp_balance_before: u64, + expected_lp_increase: u64, +) { + let lp_balance_after = get_token_balance(rpc, owner_lp_token).await; + let actual_increase = lp_balance_after.saturating_sub(lp_balance_before); + assert!( + actual_increase >= expected_lp_increase, + "LP token balance should increase by at least {}. Before: {}, After: {}, Actual increase: {}", + expected_lp_increase, + lp_balance_before, + lp_balance_after, + actual_increase + ); +} + +/// Assert that swap succeeded by checking balances changed correctly. +pub async fn assert_swap_succeeded( + rpc: &mut LightProgramTest, + input_account: Pubkey, + output_account: Pubkey, + input_balance_before: u64, + output_balance_before: u64, + expected_input_decrease: u64, + min_output_increase: u64, +) { + let input_balance_after = get_token_balance(rpc, input_account).await; + let output_balance_after = get_token_balance(rpc, output_account).await; + + let actual_input_decrease = input_balance_before.saturating_sub(input_balance_after); + let actual_output_increase = output_balance_after.saturating_sub(output_balance_before); + + assert_eq!( + actual_input_decrease, expected_input_decrease, + "Input token balance should decrease by {}. Before: {}, After: {}", + expected_input_decrease, input_balance_before, input_balance_after + ); + + assert!( + actual_output_increase >= min_output_increase, + "Output token balance should increase by at least {}. Before: {}, After: {}, Actual: {}", + min_output_increase, + output_balance_before, + output_balance_after, + actual_output_increase + ); +} + +/// Assert that withdraw succeeded by checking LP token balance decreased. +pub async fn assert_withdraw_succeeded( + rpc: &mut LightProgramTest, + owner_lp_token: Pubkey, + lp_balance_before: u64, + expected_lp_decrease: u64, +) { + let lp_balance_after = get_token_balance(rpc, owner_lp_token).await; + let actual_decrease = lp_balance_before.saturating_sub(lp_balance_after); + assert_eq!( + actual_decrease, expected_lp_decrease, + "LP token balance should decrease by {}. Before: {}, After: {}", + expected_lp_decrease, lp_balance_before, lp_balance_after + ); +} + +/// Verify that the AMM config was created. +pub async fn assert_amm_config_created(rpc: &mut LightProgramTest, amm_config: Pubkey) { + let account = rpc.get_account(amm_config).await.unwrap(); + assert!(account.is_some(), "AmmConfig account should exist"); +} + +// ============================================================================ +// Unified Setup Functions for SDK-based Tests +// ============================================================================ + +/// Complete pool setup result containing all necessary state. +pub struct PoolSetup { + pub env: TestEnv, + pub creator: Keypair, + pub tokens: TokenSetup, + pub amm_config: Pubkey, + pub pdas: AmmPdas, +} + +/// Setup a complete pool environment in a single call. +pub async fn setup_pool_environment(program_id: Pubkey, amm_config_index: u16) -> PoolSetup { + let mut env = setup_test_environment(program_id).await; + + let creator = Keypair::new(); + env.rpc + .airdrop_lamports(&creator.pubkey(), 100_000_000_000) + .await + .unwrap(); + + let admin = get_admin_keypair(); + env.rpc + .airdrop_lamports(&admin.pubkey(), 10_000_000_000) + .await + .unwrap(); + + let initial_balance = 1_000_000; + let tokens = setup_token_mints(&mut env.rpc, &env.payer, &creator.pubkey(), initial_balance).await; + + let amm_config = create_amm_config(&mut env.rpc, &env.payer, &admin, program_id, amm_config_index).await; + setup_create_pool_fee_account(&mut env.rpc, &env.payer.pubkey()); + + let pdas = derive_amm_pdas( + &program_id, + &amm_config, + &tokens.token_0_mint, + &tokens.token_1_mint, + &creator.pubkey(), + ); + + PoolSetup { + env, + creator, + tokens, + amm_config, + pdas, + } +} diff --git a/programs/cp-swap/tests/program.rs b/programs/cp-swap/tests/program.rs new file mode 100644 index 0000000..3af4711 --- /dev/null +++ b/programs/cp-swap/tests/program.rs @@ -0,0 +1,567 @@ +#![allow(dead_code)] + +/// CpSwap SDK implementing LightProgramInterface trait. +/// +/// Provides: +/// - Parsing pool accounts from AccountInterface +/// - Tracking account state (hot/cold) +/// - Building AccountSpec for load instructions + +use anchor_lang::AnchorDeserialize; +use light_client::interface::{ + AccountInterface, AccountSpec, AccountToFetch, ColdContext, LightProgramInterface, PdaSpec, + TokenAccountInterface, +}; +use light_sdk::LightDiscriminator; +use light_token::compat::{CTokenData, TokenData}; +use raydium_cp_swap::instructions::initialize::LP_MINT_SIGNER_SEED; +use raydium_cp_swap::{ + raydium_cp_swap::{LightAccountVariant, TokenAccountVariant}, + states::{ObservationState, PoolState}, + AUTH_SEED, +}; +use solana_pubkey::Pubkey; +use std::collections::HashMap; + +pub const PROGRAM_ID: Pubkey = raydium_cp_swap::ID; + +/// Instructions supported by the cp-swap program. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum CpSwapInstruction { + Swap, + Deposit, + Withdraw, +} + +/// Error type for SDK operations. +#[derive(Debug, Clone)] +pub enum CpSwapSdkError { + ParseError(String), + UnknownDiscriminator([u8; 8]), + MissingField(&'static str), + PoolStateNotParsed, + AccountNotFound(Pubkey), +} + +impl std::fmt::Display for CpSwapSdkError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::ParseError(msg) => write!(f, "Parse error: {}", msg), + Self::UnknownDiscriminator(disc) => write!(f, "Unknown discriminator: {:?}", disc), + Self::MissingField(field) => write!(f, "Missing field: {}", field), + Self::PoolStateNotParsed => write!(f, "Pool state must be parsed first"), + Self::AccountNotFound(key) => write!(f, "Account not found: {}", key), + } + } +} + +impl std::error::Error for CpSwapSdkError {} + +/// SDK for managing cp-swap pool accounts and building decompression instructions. +#[derive(Debug, Clone)] +pub struct CpSwapSdk { + /// Pool state pubkey + pub pool_state_pubkey: Option, + /// AMM config pubkey + pub amm_config: Option, + /// Token 0 mint pubkey + pub token_0_mint: Option, + /// Token 1 mint pubkey + pub token_1_mint: Option, + /// Token 0 vault pubkey + pub token_0_vault: Option, + /// Token 1 vault pubkey + pub token_1_vault: Option, + /// LP mint pubkey + pub lp_mint: Option, + /// LP mint signer pubkey + pub lp_mint_signer: Option, + /// Observation state pubkey + pub observation_key: Option, + /// Authority pubkey + pub authority: Option, + /// Cached PDA specs keyed by pubkey (includes pool_state, observation, and vaults) + pda_specs: HashMap>, + /// Cached mint interfaces keyed by pubkey + mint_specs: HashMap, +} + +impl Default for CpSwapSdk { + fn default() -> Self { + Self::new() + } +} + +impl CpSwapSdk { + /// Create a new empty SDK instance. + pub fn new() -> Self { + Self { + pool_state_pubkey: None, + amm_config: None, + token_0_mint: None, + token_1_mint: None, + token_0_vault: None, + token_1_vault: None, + lp_mint: None, + lp_mint_signer: None, + observation_key: None, + authority: None, + pda_specs: HashMap::new(), + mint_specs: HashMap::new(), + } + } + + /// Parse pool state from AccountInterface and populate SDK fields. + fn parse_pool_state(&mut self, interface: AccountInterface) -> Result<(), CpSwapSdkError> { + let data = interface.data(); + if data.len() < 8 { + return Err(CpSwapSdkError::ParseError( + "Account data too short".to_string(), + )); + } + + // Skip 8-byte discriminator + let pool_state = PoolState::deserialize(&mut &data[8..]) + .map_err(|e| CpSwapSdkError::ParseError(e.to_string()))?; + + let pool_pubkey = interface.key; + self.pool_state_pubkey = Some(pool_pubkey); + self.amm_config = Some(pool_state.amm_config); + self.token_0_mint = Some(pool_state.token_0_mint); + self.token_1_mint = Some(pool_state.token_1_mint); + self.token_0_vault = Some(pool_state.token_0_vault); + self.token_1_vault = Some(pool_state.token_1_vault); + self.lp_mint = Some(pool_state.lp_mint); + self.observation_key = Some(pool_state.observation_key); + + // Derive lp_mint_signer and authority PDAs + let (lp_mint_signer, _) = + Pubkey::find_program_address(&[LP_MINT_SIGNER_SEED, pool_pubkey.as_ref()], &PROGRAM_ID); + self.lp_mint_signer = Some(lp_mint_signer); + + let (authority, _) = Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &PROGRAM_ID); + self.authority = Some(authority); + + // Create PdaSpec with variant + let variant = LightAccountVariant::PoolState { + data: pool_state.clone(), + amm_config: pool_state.amm_config, + token_0_mint: pool_state.token_0_mint, + token_1_mint: pool_state.token_1_mint, + }; + let spec = PdaSpec::new(interface, variant, PROGRAM_ID); + self.pda_specs.insert(pool_pubkey, spec); + + Ok(()) + } + + /// Parse observation state from AccountInterface. + fn parse_observation_state(&mut self, interface: AccountInterface) -> Result<(), CpSwapSdkError> { + let pool_state = self + .pool_state_pubkey + .ok_or(CpSwapSdkError::PoolStateNotParsed)?; + + let data = interface.data(); + if data.len() < 8 { + return Err(CpSwapSdkError::ParseError( + "Account data too short".to_string(), + )); + } + + let obs_pubkey = interface.key; + let obs_state = ObservationState::deserialize(&mut &data[8..]) + .map_err(|e| CpSwapSdkError::ParseError(e.to_string()))?; + + let variant = LightAccountVariant::ObservationState { + data: obs_state, + pool_state, + }; + let spec = PdaSpec::new(interface, variant, PROGRAM_ID); + self.pda_specs.insert(obs_pubkey, spec); + + Ok(()) + } + + /// Store token vault interface. + /// Vaults are program-owned PDAs, so we convert them to PdaSpec with CTokenData variant. + pub fn set_token_vault(&mut self, interface: TokenAccountInterface, is_vault_0: bool) { + let key = interface.key; + let pool_state = self.pool_state_pubkey.expect("pool_state must be set before vaults"); + let mint = if is_vault_0 { + self.token_0_mint.expect("token_0_mint must be set") + } else { + self.token_1_mint.expect("token_1_mint must be set") + }; + + // Build TokenData from TokenAccountInterface + let token_data = TokenData { + mint: interface.mint(), + owner: interface.owner(), + amount: interface.amount(), + delegate: if interface.parsed.delegate.option == [1, 0, 0, 0] { + Some(Pubkey::from(interface.parsed.delegate.value)) + } else { + None + }, + state: light_token::compat::AccountState::Initialized, + tlv: None, + }; + + // Build variant based on which vault this is + let variant = if is_vault_0 { + LightAccountVariant::CTokenData(CTokenData { + variant: TokenAccountVariant::Token0Vault { + pool_state, + token_0_mint: mint, + }, + token_data, + }) + } else { + LightAccountVariant::CTokenData(CTokenData { + variant: TokenAccountVariant::Token1Vault { + pool_state, + token_1_mint: mint, + }, + token_data, + }) + }; + + // Convert TokenAccountInterface to AccountInterface for PdaSpec + // For cold vaults, we need to convert ColdContext::Token to ColdContext::Account + let cold = if let Some(ColdContext::Token(ct)) = &interface.cold { + Some(ColdContext::Account(ct.account.clone())) + } else { + None + }; + + let account_interface = AccountInterface { + key, + account: interface.account.clone(), + cold, + }; + + let spec = PdaSpec::new(account_interface, variant, PROGRAM_ID); + + self.pda_specs.insert(key, spec); + if is_vault_0 { + self.token_0_vault = Some(key); + } else { + self.token_1_vault = Some(key); + } + } + + /// Store LP mint interface. + pub fn set_lp_mint(&mut self, interface: AccountInterface) { + let key = interface.key; + self.lp_mint = Some(key); + self.mint_specs.insert(key, interface); + } + + /// Parse token vault from AccountInterface and store as PdaSpec. + fn parse_token_vault( + &mut self, + account: &AccountInterface, + is_vault_0: bool, + ) -> Result<(), CpSwapSdkError> { + let pool_state = self + .pool_state_pubkey + .ok_or(CpSwapSdkError::PoolStateNotParsed)?; + + // Deserialize token data properly + let token_data = TokenData::deserialize(&mut &account.data()[..]) + .map_err(|e| CpSwapSdkError::ParseError(e.to_string()))?; + + // Build variant based on which vault this is + let variant = if is_vault_0 { + let token_0_mint = self + .token_0_mint + .ok_or(CpSwapSdkError::MissingField("token_0_mint"))?; + LightAccountVariant::CTokenData(CTokenData { + variant: TokenAccountVariant::Token0Vault { + pool_state, + token_0_mint, + }, + token_data, + }) + } else { + let token_1_mint = self + .token_1_mint + .ok_or(CpSwapSdkError::MissingField("token_1_mint"))?; + LightAccountVariant::CTokenData(CTokenData { + variant: TokenAccountVariant::Token1Vault { + pool_state, + token_1_mint, + }, + token_data, + }) + }; + + // For token vaults, convert ColdContext::Token to ColdContext::Account + // because they're decompressed as PDAs, not as token accounts + let interface = if account.is_cold() { + let compressed_account = match &account.cold { + Some(ColdContext::Token(ct)) => ct.account.clone(), + Some(ColdContext::Account(ca)) => ca.clone(), + None => return Err(CpSwapSdkError::MissingField("cold_context")), + }; + AccountInterface { + key: account.key, + account: account.account.clone(), + cold: Some(ColdContext::Account(compressed_account)), + } + } else { + account.clone() + }; + + let spec = PdaSpec::new(interface, variant, PROGRAM_ID); + self.pda_specs.insert(account.key, spec); + + Ok(()) + } + + /// Parse LP mint from AccountInterface. + fn parse_mint(&mut self, account: &AccountInterface) -> Result<(), CpSwapSdkError> { + self.mint_specs.insert(account.key, account.clone()); + Ok(()) + } + + /// Parse any account and route to appropriate parser. + fn parse_account(&mut self, account: &AccountInterface) -> Result<(), CpSwapSdkError> { + // Check if this is a known vault by pubkey + if Some(account.key) == self.token_0_vault { + return self.parse_token_vault(account, true); + } + if Some(account.key) == self.token_1_vault { + return self.parse_token_vault(account, false); + } + + // Check discriminator for pool/observation state + let data = account.data(); + if data.len() >= 8 { + let discriminator: [u8; 8] = data[..8].try_into().unwrap_or_default(); + + if discriminator == PoolState::LIGHT_DISCRIMINATOR { + return self.parse_pool_state(account.clone()); + } + if discriminator == ObservationState::LIGHT_DISCRIMINATOR { + return self.parse_observation_state(account.clone()); + } + } + + // Check if this is an LP mint by matching the signer + if let Some(lp_mint_signer) = self.lp_mint_signer { + if let Some(mint_signer) = account.mint_signer() { + if Pubkey::new_from_array(mint_signer) == lp_mint_signer { + return self.parse_mint(account); + } + } + } + + // Check if this is a vault mint (token_0_mint or token_1_mint) + if Some(account.key) == self.token_0_mint || Some(account.key) == self.token_1_mint { + return self.parse_mint(account); + } + + Ok(()) + } + + /// Check if pool state is cold. + pub fn is_pool_state_cold(&self) -> bool { + self.pool_state_pubkey + .and_then(|k| self.pda_specs.get(&k)) + .map_or(false, |s| s.is_cold()) + } + + /// Check if observation state is cold. + pub fn is_observation_cold(&self) -> bool { + self.observation_key + .and_then(|k| self.pda_specs.get(&k)) + .map_or(false, |s| s.is_cold()) + } + + /// Check if token 0 vault is cold. + pub fn is_vault_0_cold(&self) -> bool { + self.token_0_vault + .and_then(|k| self.pda_specs.get(&k)) + .map_or(false, |s| s.is_cold()) + } + + /// Check if token 1 vault is cold. + pub fn is_vault_1_cold(&self) -> bool { + self.token_1_vault + .and_then(|k| self.pda_specs.get(&k)) + .map_or(false, |s| s.is_cold()) + } + + /// Check if LP mint is cold. + pub fn is_lp_mint_cold(&self) -> bool { + self.lp_mint + .and_then(|k| self.mint_specs.get(&k)) + .map_or(false, |s| s.is_cold()) + } + + /// Get pool state pubkey. + pub fn pool_state(&self) -> Option { + self.pool_state_pubkey + } +} + +impl LightProgramInterface for CpSwapSdk { + type Variant = LightAccountVariant; + type Instruction = CpSwapInstruction; + type Error = CpSwapSdkError; + + fn program_id(&self) -> Pubkey { + PROGRAM_ID + } + + fn from_keyed_accounts(accounts: &[AccountInterface]) -> Result { + let mut sdk = Self::new(); + + // First pass: find and parse pool state + for account in accounts { + let data = account.data(); + if data.len() >= 8 { + let discriminator: [u8; 8] = data[..8].try_into().unwrap_or_default(); + if discriminator == PoolState::LIGHT_DISCRIMINATOR { + sdk.parse_pool_state(account.clone())?; + break; + } + } + } + + if sdk.pool_state_pubkey.is_none() { + return Err(CpSwapSdkError::MissingField("pool_state")); + } + + // Second pass: parse other accounts + for account in accounts { + let data = account.data(); + if data.len() >= 8 { + let discriminator: [u8; 8] = data[..8].try_into().unwrap_or_default(); + if discriminator == ObservationState::LIGHT_DISCRIMINATOR { + sdk.parse_observation_state(account.clone())?; + } + } + } + + Ok(sdk) + } + + fn get_accounts_to_update(&self, ix: &Self::Instruction) -> Vec { + let mut accounts = Vec::new(); + + // All instructions need pool_state and observation_state + if let Some(pubkey) = self.pool_state_pubkey { + accounts.push(AccountToFetch::pda(pubkey, PROGRAM_ID)); + } + if let Some(pubkey) = self.observation_key { + accounts.push(AccountToFetch::pda(pubkey, PROGRAM_ID)); + } + + // All instructions need token vaults + if let Some(pubkey) = self.token_0_vault { + accounts.push(AccountToFetch::token(pubkey)); + } + if let Some(pubkey) = self.token_1_vault { + accounts.push(AccountToFetch::token(pubkey)); + } + + // All instructions need vault mints (token_0_mint and token_1_mint) + if let Some(pubkey) = self.token_0_mint { + accounts.push(AccountToFetch::mint(pubkey)); + } + if let Some(pubkey) = self.token_1_mint { + accounts.push(AccountToFetch::mint(pubkey)); + } + + // Deposit and Withdraw also need LP mint + match ix { + CpSwapInstruction::Deposit | CpSwapInstruction::Withdraw => { + if let Some(pubkey) = self.lp_mint { + accounts.push(AccountToFetch::mint(pubkey)); + } + } + CpSwapInstruction::Swap => {} + } + + accounts + } + + fn update(&mut self, accounts: &[AccountInterface]) -> Result<(), Self::Error> { + for account in accounts { + self.parse_account(account)?; + } + Ok(()) + } + + fn get_all_specs(&self) -> Vec> { + let mut specs = Vec::new(); + + // Add PDA specs (includes pool_state, observation, and vaults) + for spec in self.pda_specs.values() { + specs.push(AccountSpec::Pda(spec.clone())); + } + + // Add mint specs + for spec in self.mint_specs.values() { + specs.push(AccountSpec::Mint(spec.clone())); + } + + specs + } + + fn get_specs_for_instruction(&self, ix: &Self::Instruction) -> Vec> { + let mut specs = Vec::new(); + + // Pool state and observation state needed for all instructions + if let Some(pubkey) = self.pool_state_pubkey { + if let Some(spec) = self.pda_specs.get(&pubkey) { + specs.push(AccountSpec::Pda(spec.clone())); + } + } + if let Some(pubkey) = self.observation_key { + if let Some(spec) = self.pda_specs.get(&pubkey) { + specs.push(AccountSpec::Pda(spec.clone())); + } + } + + // Token vaults needed for all instructions (stored as PDA specs with CTokenData variant) + if let Some(pubkey) = self.token_0_vault { + if let Some(spec) = self.pda_specs.get(&pubkey) { + specs.push(AccountSpec::Pda(spec.clone())); + } + } + if let Some(pubkey) = self.token_1_vault { + if let Some(spec) = self.pda_specs.get(&pubkey) { + specs.push(AccountSpec::Pda(spec.clone())); + } + } + + // Vault mints (token_0_mint and token_1_mint) needed for all instructions + if let Some(pubkey) = self.token_0_mint { + if let Some(spec) = self.mint_specs.get(&pubkey) { + specs.push(AccountSpec::Mint(spec.clone())); + } + } + if let Some(pubkey) = self.token_1_mint { + if let Some(spec) = self.mint_specs.get(&pubkey) { + specs.push(AccountSpec::Mint(spec.clone())); + } + } + + // LP mint needed for deposit/withdraw + match ix { + CpSwapInstruction::Deposit | CpSwapInstruction::Withdraw => { + if let Some(pubkey) = self.lp_mint { + if let Some(spec) = self.mint_specs.get(&pubkey) { + specs.push(AccountSpec::Mint(spec.clone())); + } + } + } + CpSwapInstruction::Swap => {} + } + + specs + } +} diff --git a/programs/cp-swap/tests/program_test.rs b/programs/cp-swap/tests/program_test.rs new file mode 100644 index 0000000..78a5fda --- /dev/null +++ b/programs/cp-swap/tests/program_test.rs @@ -0,0 +1,223 @@ +/// Clean integration test for cp-swap using CpSwapSdk. +/// Tests the full lifecycle: Initialize -> Warp -> Compress -> Load -> Execute Operations + +use light_client::interface::{ + create_load_instructions, AccountInterfaceExt, AccountSpec, LightProgramInterface, +}; +use light_program_test::program_test::TestRpc; +use light_program_test::Rpc; +use solana_instruction::Instruction; +use solana_sdk::transaction::Transaction; +use solana_signer::Signer; + +mod helpers; +mod program; + +use helpers::*; +use program::{CpSwapInstruction, CpSwapSdk}; + +fn log_transaction_size(name: &str, ixs: &[Instruction]) { + let tx = Transaction::new_with_payer(ixs, None); + let serialized = bincode::serialize(&tx).expect("Failed to serialize transaction"); + println!("{}: {} bytes ({} instructions)", name, serialized.len(), ixs.len()); +} + +#[tokio::test] +async fn test_sdk_lifecycle() { + let program_id = raydium_cp_swap::ID; + + // ==================== PHASE 1: Setup & Initialize Pool ==================== + let mut setup = setup_pool_environment(program_id, 10).await; + + let proof_result = + get_pool_create_accounts_proof(&setup.env.rpc, &program_id, &setup.pdas).await; + let init_ix = build_initialize_instruction( + program_id, + setup.creator.pubkey(), + setup.amm_config, + &setup.pdas, + &setup.tokens, + setup.env.config_pda, + &proof_result, + 100_000, + 100_000, + 0, + ); + log_transaction_size("Initialize transaction", &[init_ix.clone()]); + setup + .env + .rpc + .create_and_send_transaction(&[init_ix], &setup.creator.pubkey(), &[&setup.creator]) + .await + .unwrap(); + + // ==================== PHASE 2: Verify Hot Accounts Exist ==================== + assert_pool_accounts_exist(&mut setup.env.rpc, &setup.pdas, &setup.tokens).await; + + // ==================== PHASE 3: Warp to Trigger Compression ==================== + setup + .env + .rpc + .warp_epoch_forward(30) + .await + .unwrap(); + + // ==================== PHASE 4: Assert All Accounts Are Compressed ==================== + assert_pool_accounts_compressed(&mut setup.env.rpc, &setup.pdas, &setup.tokens).await; + + // ==================== PHASE 5: Create SDK from Compressed State ==================== + let pool_interface = setup + .env + .rpc + .get_account_interface(&setup.pdas.pool_state, &program_id) + .await + .expect("pool should be compressed"); + assert!( + pool_interface.is_cold(), + "pool_state should be cold after warp" + ); + + let mut sdk = CpSwapSdk::from_keyed_accounts(&[pool_interface]) + .expect("from_keyed_accounts should succeed"); + + // ==================== PHASE 6: Fetch & Update SDK ==================== + let accounts_to_fetch = sdk.get_accounts_to_update(&CpSwapInstruction::Deposit); + let keyed_accounts = setup + .env + .rpc + .get_multiple_account_interfaces(&accounts_to_fetch) + .await + .expect("get_multiple_account_interfaces should succeed"); + + sdk.update(&keyed_accounts) + .expect("sdk.update should succeed"); + + // ==================== PHASE 7: Build Specs for Load ==================== + let mut all_specs = sdk.get_specs_for_instruction(&CpSwapInstruction::Deposit); + + // Fetch creator's ATAs (compressed) and add to specs + let creator_lp_ata_interface = setup + .env + .rpc + .get_ata_interface(&setup.creator.pubkey(), &setup.pdas.lp_mint) + .await + .expect("get_ata_interface for creator_lp_token should succeed"); + all_specs.push(AccountSpec::Ata(creator_lp_ata_interface)); + + let creator_token_0_interface = setup + .env + .rpc + .get_ata_interface(&setup.creator.pubkey(), &setup.tokens.token_0_mint) + .await + .expect("get_ata_interface for creator_token_0 should succeed"); + all_specs.push(AccountSpec::Ata(creator_token_0_interface)); + + let creator_token_1_interface = setup + .env + .rpc + .get_ata_interface(&setup.creator.pubkey(), &setup.tokens.token_1_mint) + .await + .expect("get_ata_interface for creator_token_1 should succeed"); + all_specs.push(AccountSpec::Ata(creator_token_1_interface)); + + // ==================== PHASE 8: Create Load Instructions ==================== + let all_load_ixs = create_load_instructions( + &all_specs, + setup.env.payer.pubkey(), + setup.env.config_pda, + setup.env.payer.pubkey(), + &setup.env.rpc, + ) + .await + .expect("create_load_instructions should succeed"); + + // ==================== PHASE 9: Execute Load ==================== + log_transaction_size("Load transaction", &all_load_ixs); + setup + .env + .rpc + .create_and_send_transaction( + &all_load_ixs, + &setup.env.payer.pubkey(), + &[&setup.env.payer, &setup.creator], + ) + .await + .expect("Load should succeed"); + + // ==================== PHASE 10: Verify Accounts Are Loaded ==================== + assert_pool_accounts_exist(&mut setup.env.rpc, &setup.pdas, &setup.tokens).await; + + // ==================== PHASE 11: Execute Operations ==================== + // Deposit + let deposit_ix = build_deposit_instruction( + program_id, + setup.creator.pubkey(), + &setup.pdas, + &setup.tokens, + setup.tokens.creator_token_0, + setup.tokens.creator_token_1, + 500, + 10_000, + 10_000, + ); + log_transaction_size("Deposit transaction", &[deposit_ix.clone()]); + + // Log combined Load + Deposit + let mut load_plus_deposit = all_load_ixs.clone(); + load_plus_deposit.push(deposit_ix.clone()); + log_transaction_size("Load + Deposit transaction", &load_plus_deposit); + + setup + .env + .rpc + .create_and_send_transaction(&[deposit_ix], &setup.creator.pubkey(), &[&setup.creator]) + .await + .unwrap(); + + // Swap + let swap_ix = build_swap_instruction( + program_id, + setup.creator.pubkey(), + setup.amm_config, + &setup.pdas, + &setup.tokens, + setup.tokens.creator_token_0, + setup.tokens.creator_token_1, + true, + 100, + 1, + ); + log_transaction_size("Swap transaction", &[swap_ix.clone()]); + + // Log combined Load + Swap + let mut load_plus_swap = all_load_ixs.clone(); + load_plus_swap.push(swap_ix.clone()); + log_transaction_size("Load + Swap transaction", &load_plus_swap); + + setup + .env + .rpc + .create_and_send_transaction(&[swap_ix], &setup.creator.pubkey(), &[&setup.creator]) + .await + .unwrap(); + + // Withdraw + let lp_balance = get_token_balance(&mut setup.env.rpc, setup.pdas.creator_lp_token).await; + let withdraw_ix = build_withdraw_instruction( + program_id, + setup.creator.pubkey(), + &setup.pdas, + &setup.tokens, + setup.tokens.creator_token_0, + setup.tokens.creator_token_1, + lp_balance / 2, + 0, + 0, + ); + setup + .env + .rpc + .create_and_send_transaction(&[withdraw_ix], &setup.creator.pubkey(), &[&setup.creator]) + .await + .unwrap(); +} diff --git a/tests/deposit.test.ts b/tests/deposit.test.ts deleted file mode 100644 index 70ce31a..0000000 --- a/tests/deposit.test.ts +++ /dev/null @@ -1,337 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program, BN } from "@coral-xyz/anchor"; -import { RaydiumCpSwap } from "../target/types/raydium_cp_swap"; -import { - calculateFee, - calculatePreFeeAmount, - deposit, - getUserAndPoolVaultAmount, - setupDepositTest, -} from "./utils"; -import { assert } from "chai"; -import { MAX_FEE_BASIS_POINTS, TOKEN_PROGRAM_ID } from "@solana/spl-token"; - -describe("deposit test", () => { - anchor.setProvider(anchor.AnchorProvider.env()); - const owner = anchor.Wallet.local().payer; - - const program = anchor.workspace.RaydiumCpSwap as Program; - - const confirmOptions = { - skipPreflight: true, - }; - - it("deposit test, add the same liquidity and check the correctness of the values with and without transfer fees", async () => { - /// deposit without fee - const { poolAddress, poolState } = await setupDepositTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 } - ); - - const { - onwerToken0Account: ownerToken0AccountBefore, - onwerToken1Account: ownerToken1AccountBefore, - poolVault0TokenAccount: poolVault0TokenAccountBefore, - poolVault1TokenAccount: poolVault1TokenAccountBefore, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - - const liquidity = new BN(10000000000); - await deposit( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity, - new BN(10000000000), - new BN(20000000000), - confirmOptions - ); - const newPoolState = await program.account.poolState.fetch(poolAddress); - assert(newPoolState.lpSupply.eq(liquidity.add(poolState.lpSupply))); - - const { - onwerToken0Account: ownerToken0AccountAfter, - onwerToken1Account: ownerToken1AccountAfter, - poolVault0TokenAccount: poolVault0TokenAccountAfter, - poolVault1TokenAccount: poolVault1TokenAccountAfter, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - const input_token0_amount = - ownerToken0AccountBefore.amount - ownerToken0AccountAfter.amount; - const input_token1_amount = - ownerToken1AccountBefore.amount - ownerToken1AccountAfter.amount; - assert.equal( - poolVault0TokenAccountAfter.amount - poolVault0TokenAccountBefore.amount, - input_token0_amount - ); - assert.equal( - poolVault1TokenAccountAfter.amount - poolVault1TokenAccountBefore.amount, - input_token1_amount - ); - - /// deposit with fee - const transferFeeConfig = { - transferFeeBasisPoints: 100, - MaxFee: 50000000000, - }; // %10 - - // Ensure that the initialization state is the same with depsoit without fee - const { poolAddress: poolAddress2, poolState: poolState2 } = - await setupDepositTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - transferFeeConfig, - confirmOptions, - { - initAmount0: new BN( - calculatePreFeeAmount( - transferFeeConfig, - poolVault0TokenAccountBefore.amount, - poolState.token0Program - ).toString() - ), - initAmount1: new BN( - calculatePreFeeAmount( - transferFeeConfig, - poolVault1TokenAccountBefore.amount, - poolState.token1Program - ).toString() - ), - }, - { - token0Program: poolState.token0Program, - token1Program: poolState.token1Program, - } - ); - const { - onwerToken0Account: onwerToken0AccountBefore2, - onwerToken1Account: onwerToken1AccountBefore2, - poolVault0TokenAccount: poolVault0TokenAccountBefore2, - poolVault1TokenAccount: poolVault1TokenAccountBefore2, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState2.token0Mint, - poolState2.token0Program, - poolState2.token1Mint, - poolState2.token1Program, - poolState2.token0Vault, - poolState2.token1Vault - ); - // check vault init state - assert.equal( - poolVault0TokenAccountBefore2.amount, - poolVault0TokenAccountBefore.amount - ); - assert.equal( - poolVault1TokenAccountBefore2.amount, - poolVault1TokenAccountBefore.amount - ); - - await deposit( - program, - owner, - poolState2.ammConfig, - poolState2.token0Mint, - poolState2.token0Program, - poolState2.token1Mint, - poolState2.token1Program, - liquidity, - new BN(100000000000), - new BN(200000000000), - confirmOptions - ); - const newPoolState2 = await program.account.poolState.fetch(poolAddress2); - assert(newPoolState2.lpSupply.eq(liquidity.add(poolState2.lpSupply))); - - const { - onwerToken0Account: onwerToken0AccountAfter2, - onwerToken1Account: onwerToken1AccountAfter2, - poolVault0TokenAccount: poolVault0TokenAccountAfter2, - poolVault1TokenAccount: poolVault1TokenAccountAfter2, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState2.token0Mint, - poolState2.token0Program, - poolState2.token1Mint, - poolState2.token1Program, - poolState2.token0Vault, - poolState2.token1Vault - ); - - const input_token0_amount_with_fee = - onwerToken0AccountBefore2.amount - onwerToken0AccountAfter2.amount; - const input_token1_amount_with_fee = - onwerToken1AccountBefore2.amount - onwerToken1AccountAfter2.amount; - assert(input_token0_amount_with_fee >= input_token0_amount); - assert(input_token1_amount_with_fee >= input_token1_amount); - - assert.equal( - input_token0_amount_with_fee, - calculateFee( - transferFeeConfig, - input_token0_amount_with_fee, - poolState2.token0Program - ) + input_token0_amount - ); - assert.equal( - input_token1_amount_with_fee, - calculateFee( - transferFeeConfig, - input_token1_amount_with_fee, - poolState2.token1Program - ) + input_token1_amount - ); - - // Add the same liquidity, the amount increment of the pool vault will be the same as without fees. - assert.equal( - poolVault0TokenAccountAfter2.amount - - poolVault0TokenAccountBefore2.amount, - input_token0_amount - ); - assert.equal( - poolVault1TokenAccountAfter2.amount - - poolVault1TokenAccountBefore2.amount, - input_token1_amount - ); - - assert.equal( - poolVault0TokenAccountAfter.amount, - poolVault0TokenAccountAfter2.amount - ); - assert.equal( - poolVault1TokenAccountAfter.amount, - poolVault1TokenAccountAfter2.amount - ); - }); - - it("deposit test with 100% transferFeeConfig, reache maximum fee limit", async () => { - const transferFeeConfig = { - transferFeeBasisPoints: MAX_FEE_BASIS_POINTS, - MaxFee: 5000000000, - }; // %100 - - const { poolAddress, poolState } = await setupDepositTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - transferFeeConfig - ); - - const { - onwerToken0Account: ownerToken0AccountBefore, - onwerToken1Account: ownerToken1AccountBefore, - poolVault0TokenAccount: poolVault0TokenAccountBefore, - poolVault1TokenAccount: poolVault1TokenAccountBefore, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - - const liquidity = new BN(10000000000); - await deposit( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity, - new BN(10000000000), - new BN(20000000000), - confirmOptions - ); - const newPoolState = await program.account.poolState.fetch(poolAddress); - assert(newPoolState.lpSupply.eq(liquidity.add(poolState.lpSupply))); - - const { - onwerToken0Account: ownerToken0AccountAfter, - onwerToken1Account: ownerToken1AccountAfter, - poolVault0TokenAccount: poolVault0TokenAccountAfter, - poolVault1TokenAccount: poolVault1TokenAccountAfter, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - const input_token0_amount = - ownerToken0AccountBefore.amount - ownerToken0AccountAfter.amount; - const input_token1_amount = - ownerToken1AccountBefore.amount - ownerToken1AccountAfter.amount; - - if (poolState.token0Program.equals(TOKEN_PROGRAM_ID)) { - assert.equal( - poolVault0TokenAccountAfter.amount - - poolVault0TokenAccountBefore.amount, - input_token0_amount - ); - assert.equal( - poolVault1TokenAccountAfter.amount - - poolVault1TokenAccountBefore.amount, - input_token1_amount - BigInt(transferFeeConfig.MaxFee) - ); - } else { - assert.equal( - poolVault0TokenAccountAfter.amount - - poolVault0TokenAccountBefore.amount, - input_token0_amount - BigInt(transferFeeConfig.MaxFee) - ); - assert.equal( - poolVault1TokenAccountAfter.amount - - poolVault1TokenAccountBefore.amount, - input_token1_amount - ); - } - }); -}); diff --git a/tests/initialize.test.ts b/tests/initialize.test.ts deleted file mode 100644 index f352600..0000000 --- a/tests/initialize.test.ts +++ /dev/null @@ -1,183 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program, BN } from "@coral-xyz/anchor"; -import { RaydiumCpSwap } from "../target/types/raydium_cp_swap"; - -import { getAccount, TOKEN_PROGRAM_ID } from "@solana/spl-token"; -import { setupInitializeTest, initialize, calculateFee } from "./utils"; -import { assert } from "chai"; - -describe("initialize test", () => { - anchor.setProvider(anchor.AnchorProvider.env()); - const owner = anchor.Wallet.local().payer; - console.log("owner: ", owner.publicKey.toString()); - - const program = anchor.workspace.RaydiumCpSwap as Program; - - const confirmOptions = { - skipPreflight: true, - }; - - it("create pool without fee", async () => { - const { configAddress, token0, token0Program, token1, token1Program } = - await setupInitializeTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 }, - confirmOptions - ); - - const initAmount0 = new BN(10000000000); - const initAmount1 = new BN(10000000000); - const { poolAddress, poolState } = await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions, - { initAmount0, initAmount1 } - ); - let vault0 = await getAccount( - anchor.getProvider().connection, - poolState.token0Vault, - "processed", - poolState.token0Program - ); - assert.equal(vault0.amount.toString(), initAmount0.toString()); - - let vault1 = await getAccount( - anchor.getProvider().connection, - poolState.token1Vault, - "processed", - poolState.token1Program - ); - assert.equal(vault1.amount.toString(), initAmount1.toString()); - }); - - it("create pool with fee", async () => { - const { configAddress, token0, token0Program, token1, token1Program } = - await setupInitializeTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(100000000), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 }, - confirmOptions - ); - - const initAmount0 = new BN(10000000000); - const initAmount1 = new BN(10000000000); - const { poolAddress, poolState } = await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions, - { initAmount0, initAmount1 } - ); - let vault0 = await getAccount( - anchor.getProvider().connection, - poolState.token0Vault, - "processed", - poolState.token0Program - ); - assert.equal(vault0.amount.toString(), initAmount0.toString()); - - let vault1 = await getAccount( - anchor.getProvider().connection, - poolState.token1Vault, - "processed", - poolState.token1Program - ); - assert.equal(vault1.amount.toString(), initAmount1.toString()); - }); - - it("create pool with token2022 mint has transfer fee", async () => { - const transferFeeConfig = { transferFeeBasisPoints: 100, MaxFee: 50000000 }; // %10 - const { configAddress, token0, token0Program, token1, token1Program } = - await setupInitializeTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(100000000), - }, - transferFeeConfig, - confirmOptions - ); - - const initAmount0 = new BN(10000000000); - const initAmount1 = new BN(10000000000); - const { poolAddress, poolState } = await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions, - { initAmount0, initAmount1 } - ); - let vault0 = await getAccount( - anchor.getProvider().connection, - poolState.token0Vault, - "processed", - poolState.token0Program - ); - if (token0Program == TOKEN_PROGRAM_ID) { - assert.equal(vault0.amount.toString(), initAmount0.toString()); - } else { - const total = - vault0.amount + - calculateFee( - transferFeeConfig, - BigInt(initAmount0.toString()), - poolState.token0Program - ); - assert(new BN(total.toString()).gte(initAmount0)); - } - - let vault1 = await getAccount( - anchor.getProvider().connection, - poolState.token1Vault, - "processed", - poolState.token1Program - ); - if (token1Program == TOKEN_PROGRAM_ID) { - assert.equal(vault1.amount.toString(), initAmount1.toString()); - } else { - const total = - vault1.amount + - calculateFee( - transferFeeConfig, - BigInt(initAmount1.toString()), - poolState.token1Program - ); - assert(new BN(total.toString()).gte(initAmount1)); - } - }); -}); diff --git a/tests/swap.test.ts b/tests/swap.test.ts deleted file mode 100644 index b637d41..0000000 --- a/tests/swap.test.ts +++ /dev/null @@ -1,200 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program, BN } from "@coral-xyz/anchor"; -import { RaydiumCpSwap } from "../target/types/raydium_cp_swap"; -import { setupSwapTest, swap_base_input, swap_base_output } from "./utils"; -import { assert } from "chai"; -import { getAccount, getAssociatedTokenAddressSync } from "@solana/spl-token"; - -describe("swap test", () => { - anchor.setProvider(anchor.AnchorProvider.env()); - const owner = anchor.Wallet.local().payer; - - const program = anchor.workspace.RaydiumCpSwap as Program; - - const confirmOptions = { - skipPreflight: true, - }; - - it("swap base input without transfer fee", async () => { - const { configAddress, poolAddress, poolState } = await setupSwapTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 } - ); - const inputToken = poolState.token0Mint; - const inputTokenProgram = poolState.token0Program; - const inputTokenAccountAddr = getAssociatedTokenAddressSync( - inputToken, - owner.publicKey, - false, - inputTokenProgram - ); - const inputTokenAccountBefore = await getAccount( - anchor.getProvider().connection, - inputTokenAccountAddr, - "processed", - inputTokenProgram - ); - await sleep(1000); - let amount_in = new BN(100000000); - await swap_base_input( - program, - owner, - configAddress, - inputToken, - inputTokenProgram, - poolState.token1Mint, - poolState.token1Program, - amount_in, - new BN(0) - ); - const inputTokenAccountAfter = await getAccount( - anchor.getProvider().connection, - inputTokenAccountAddr, - "processed", - inputTokenProgram - ); - assert.equal( - inputTokenAccountBefore.amount - inputTokenAccountAfter.amount, - BigInt(amount_in.toString()) - ); - }); - - it("swap base output without transfer fee", async () => { - const { configAddress, poolAddress, poolState } = await setupSwapTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 } - ); - const inputToken = poolState.token0Mint; - const inputTokenProgram = poolState.token0Program; - const inputTokenAccountAddr = getAssociatedTokenAddressSync( - inputToken, - owner.publicKey, - false, - inputTokenProgram - ); - const outputToken = poolState.token1Mint; - const outputTokenProgram = poolState.token1Program; - const outputTokenAccountAddr = getAssociatedTokenAddressSync( - outputToken, - owner.publicKey, - false, - outputTokenProgram - ); - const outputTokenAccountBefore = await getAccount( - anchor.getProvider().connection, - outputTokenAccountAddr, - "processed", - outputTokenProgram - ); - await sleep(1000); - let amount_out = new BN(100000000); - await swap_base_output( - program, - owner, - configAddress, - inputToken, - inputTokenProgram, - poolState.token1Mint, - poolState.token1Program, - amount_out, - new BN(10000000000000), - confirmOptions - ); - const outputTokenAccountAfter = await getAccount( - anchor.getProvider().connection, - outputTokenAccountAddr, - "processed", - outputTokenProgram - ); - assert.equal( - outputTokenAccountAfter.amount - outputTokenAccountBefore.amount, - BigInt(amount_out.toString()) - ); - }); - - it("swap base output with transfer fee", async () => { - const transferFeeConfig = { transferFeeBasisPoints: 5, MaxFee: 5000 }; // %5 - const { configAddress, poolAddress, poolState } = await setupSwapTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - transferFeeConfig - ); - - const inputToken = poolState.token0Mint; - const inputTokenProgram = poolState.token0Program; - const inputTokenAccountAddr = getAssociatedTokenAddressSync( - inputToken, - owner.publicKey, - false, - inputTokenProgram - ); - const outputToken = poolState.token1Mint; - const outputTokenProgram = poolState.token1Program; - const outputTokenAccountAddr = getAssociatedTokenAddressSync( - outputToken, - owner.publicKey, - false, - outputTokenProgram - ); - const outputTokenAccountBefore = await getAccount( - anchor.getProvider().connection, - outputTokenAccountAddr, - "processed", - outputTokenProgram - ); - await sleep(1000); - let amount_out = new BN(100000000); - await swap_base_output( - program, - owner, - configAddress, - inputToken, - inputTokenProgram, - poolState.token1Mint, - poolState.token1Program, - amount_out, - new BN(10000000000000), - confirmOptions - ); - const outputTokenAccountAfter = await getAccount( - anchor.getProvider().connection, - outputTokenAccountAddr, - "processed", - outputTokenProgram - ); - assert.equal( - outputTokenAccountAfter.amount - outputTokenAccountBefore.amount, - BigInt(amount_out.toString()) - ); - }); -}); - -function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} diff --git a/tests/utils/fee.ts b/tests/utils/fee.ts deleted file mode 100644 index d023ca9..0000000 --- a/tests/utils/fee.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - MAX_FEE_BASIS_POINTS, - ONE_IN_BASIS_POINTS, - TOKEN_PROGRAM_ID, -} from "@solana/spl-token"; -import { PublicKey } from "@solana/web3.js"; - -export function calculateFee( - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number }, - preFeeAmount: bigint, - tokenProgram: PublicKey -): bigint { - if (tokenProgram.equals(TOKEN_PROGRAM_ID)) { - return BigInt(0); - } - if (preFeeAmount === BigInt(0)) { - return BigInt(0); - } else { - const numerator = - preFeeAmount * BigInt(transferFeeConfig.transferFeeBasisPoints); - const rawFee = - (numerator + ONE_IN_BASIS_POINTS - BigInt(1)) / ONE_IN_BASIS_POINTS; - const fee = - rawFee > transferFeeConfig.MaxFee ? transferFeeConfig.MaxFee : rawFee; - return BigInt(fee); - } -} - -export function calculatePreFeeAmount( - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number }, - postFeeAmount: bigint, - tokenProgram: PublicKey -) { - if ( - transferFeeConfig.transferFeeBasisPoints == 0 || - tokenProgram.equals(TOKEN_PROGRAM_ID) - ) { - return postFeeAmount; - } else { - let numerator = postFeeAmount * BigInt(MAX_FEE_BASIS_POINTS); - let denominator = - MAX_FEE_BASIS_POINTS - transferFeeConfig.transferFeeBasisPoints; - - return (numerator + BigInt(denominator) - BigInt(1)) / BigInt(denominator); - } -} diff --git a/tests/utils/index.ts b/tests/utils/index.ts deleted file mode 100644 index 2bbbc15..0000000 --- a/tests/utils/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./web3"; -export * from "./pda"; -export * from "./util"; -export * from "./fee"; -export * from "./instruction"; diff --git a/tests/utils/instruction.ts b/tests/utils/instruction.ts deleted file mode 100644 index 39b1cac..0000000 --- a/tests/utils/instruction.ts +++ /dev/null @@ -1,644 +0,0 @@ -import { Program, BN } from "@coral-xyz/anchor"; -import { RaydiumCpSwap } from "../../target/types/raydium_cp_swap"; -import { - Connection, - ConfirmOptions, - PublicKey, - Keypair, - Signer, - SystemProgram, - SYSVAR_RENT_PUBKEY, -} from "@solana/web3.js"; -import { - TOKEN_PROGRAM_ID, - TOKEN_2022_PROGRAM_ID, - getAssociatedTokenAddressSync, -} from "@solana/spl-token"; -import { - accountExist, - sendTransaction, - getAmmConfigAddress, - getAuthAddress, - getPoolAddress, - getPoolLpMintAddress, - getPoolVaultAddress, - createTokenMintAndAssociatedTokenAccount, - getOrcleAccountAddress, -} from "./index"; - -import { ASSOCIATED_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token"; - -export async function setupInitializeTest( - program: Program, - connection: Connection, - owner: Signer, - config: { - config_index: number; - tradeFeeRate: BN; - protocolFeeRate: BN; - fundFeeRate: BN; - create_fee: BN; - }, - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number } = { - transferFeeBasisPoints: 0, - MaxFee: 0, - }, - confirmOptions?: ConfirmOptions -) { - const [{ token0, token0Program }, { token1, token1Program }] = - await createTokenMintAndAssociatedTokenAccount( - connection, - owner, - new Keypair(), - transferFeeConfig - ); - const configAddress = await createAmmConfig( - program, - connection, - owner, - config.config_index, - config.tradeFeeRate, - config.protocolFeeRate, - config.fundFeeRate, - config.create_fee, - confirmOptions - ); - return { - configAddress, - token0, - token0Program, - token1, - token1Program, - }; -} - -export async function setupDepositTest( - program: Program, - connection: Connection, - owner: Signer, - config: { - config_index: number; - tradeFeeRate: BN; - protocolFeeRate: BN; - fundFeeRate: BN; - create_fee: BN; - }, - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number } = { - transferFeeBasisPoints: 0, - MaxFee: 0, - }, - confirmOptions?: ConfirmOptions, - initAmount: { initAmount0: BN; initAmount1: BN } = { - initAmount0: new BN(10000000000), - initAmount1: new BN(20000000000), - }, - tokenProgramRequired?: { - token0Program: PublicKey; - token1Program: PublicKey; - } -) { - const configAddress = await createAmmConfig( - program, - connection, - owner, - config.config_index, - config.tradeFeeRate, - config.protocolFeeRate, - config.fundFeeRate, - config.create_fee, - confirmOptions - ); - - while (1) { - const [{ token0, token0Program }, { token1, token1Program }] = - await createTokenMintAndAssociatedTokenAccount( - connection, - owner, - new Keypair(), - transferFeeConfig - ); - - if (tokenProgramRequired != undefined) { - if ( - token0Program.equals(tokenProgramRequired.token0Program) && - token1Program.equals(tokenProgramRequired.token1Program) - ) { - return await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions, - initAmount - ); - } - } else { - return await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions, - initAmount - ); - } - } -} - -export async function setupSwapTest( - program: Program, - connection: Connection, - owner: Signer, - config: { - config_index: number; - tradeFeeRate: BN; - protocolFeeRate: BN; - fundFeeRate: BN; - create_fee: BN; - }, - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number } = { - transferFeeBasisPoints: 0, - MaxFee: 0, - }, - confirmOptions?: ConfirmOptions -) { - const configAddress = await createAmmConfig( - program, - connection, - owner, - config.config_index, - config.tradeFeeRate, - config.protocolFeeRate, - config.fundFeeRate, - config.create_fee, - confirmOptions - ); - - const [{ token0, token0Program }, { token1, token1Program }] = - await createTokenMintAndAssociatedTokenAccount( - connection, - owner, - new Keypair(), - transferFeeConfig - ); - - const { poolAddress, poolState } = await initialize( - program, - owner, - configAddress, - token0, - token0Program, - token1, - token1Program, - confirmOptions - ); - - await deposit( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - new BN(10000000000), - new BN(100000000000), - new BN(100000000000), - confirmOptions - ); - return { configAddress, poolAddress, poolState }; -} - -export async function createAmmConfig( - program: Program, - connection: Connection, - owner: Signer, - config_index: number, - tradeFeeRate: BN, - protocolFeeRate: BN, - fundFeeRate: BN, - create_fee: BN, - confirmOptions?: ConfirmOptions -): Promise { - const [address, _] = await getAmmConfigAddress( - config_index, - program.programId - ); - if (await accountExist(connection, address)) { - return address; - } - - const ix = await program.methods - .createAmmConfig( - config_index, - tradeFeeRate, - protocolFeeRate, - fundFeeRate, - create_fee - ) - .accounts({ - owner: owner.publicKey, - ammConfig: address, - systemProgram: SystemProgram.programId, - }) - .instruction(); - - const tx = await sendTransaction(connection, [ix], [owner], confirmOptions); - console.log("init amm config tx: ", tx); - return address; -} - -export async function initialize( - program: Program, - creator: Signer, - configAddress: PublicKey, - token0: PublicKey, - token0Program: PublicKey, - token1: PublicKey, - token1Program: PublicKey, - confirmOptions?: ConfirmOptions, - initAmount: { initAmount0: BN; initAmount1: BN } = { - initAmount0: new BN(10000000000), - initAmount1: new BN(20000000000), - }, - createPoolFee = new PublicKey("DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8") -) { - const [auth] = await getAuthAddress(program.programId); - const [poolAddress] = await getPoolAddress( - configAddress, - token0, - token1, - program.programId - ); - const [lpMintAddress] = await getPoolLpMintAddress( - poolAddress, - program.programId - ); - const [vault0] = await getPoolVaultAddress( - poolAddress, - token0, - program.programId - ); - const [vault1] = await getPoolVaultAddress( - poolAddress, - token1, - program.programId - ); - const [creatorLpTokenAddress] = await PublicKey.findProgramAddress( - [ - creator.publicKey.toBuffer(), - TOKEN_PROGRAM_ID.toBuffer(), - lpMintAddress.toBuffer(), - ], - ASSOCIATED_PROGRAM_ID - ); - - const [observationAddress] = await getOrcleAccountAddress( - poolAddress, - program.programId - ); - - const creatorToken0 = getAssociatedTokenAddressSync( - token0, - creator.publicKey, - false, - token0Program - ); - const creatorToken1 = getAssociatedTokenAddressSync( - token1, - creator.publicKey, - false, - token1Program - ); - await program.methods - .initialize(initAmount.initAmount0, initAmount.initAmount1, new BN(0)) - .accountsPartial({ - creator: creator.publicKey, - ammConfig: configAddress, - authority: auth, - poolState: poolAddress, - token0Mint: token0, - token1Mint: token1, - lpMint: lpMintAddress, - creatorToken0, - creatorToken1, - creatorLpToken: creatorLpTokenAddress, - token0Vault: vault0, - token1Vault: vault1, - createPoolFee, - observationState: observationAddress, - tokenProgram: TOKEN_PROGRAM_ID, - token0Program: token0Program, - token1Program: token1Program, - systemProgram: SystemProgram.programId, - rent: SYSVAR_RENT_PUBKEY, - }) - .rpc(confirmOptions); - const poolState = await program.account.poolState.fetch(poolAddress); - return { poolAddress, poolState }; -} - -export async function deposit( - program: Program, - owner: Signer, - configAddress: PublicKey, - token0: PublicKey, - token0Program: PublicKey, - token1: PublicKey, - token1Program: PublicKey, - lp_token_amount: BN, - maximum_token_0_amount: BN, - maximum_token_1_amount: BN, - confirmOptions?: ConfirmOptions -) { - const [auth] = await getAuthAddress(program.programId); - const [poolAddress] = await getPoolAddress( - configAddress, - token0, - token1, - program.programId - ); - - const [lpMintAddress] = await getPoolLpMintAddress( - poolAddress, - program.programId - ); - const [vault0] = await getPoolVaultAddress( - poolAddress, - token0, - program.programId - ); - const [vault1] = await getPoolVaultAddress( - poolAddress, - token1, - program.programId - ); - const [ownerLpToken] = await PublicKey.findProgramAddress( - [ - owner.publicKey.toBuffer(), - TOKEN_PROGRAM_ID.toBuffer(), - lpMintAddress.toBuffer(), - ], - ASSOCIATED_PROGRAM_ID - ); - - const onwerToken0 = getAssociatedTokenAddressSync( - token0, - owner.publicKey, - false, - token0Program - ); - const onwerToken1 = getAssociatedTokenAddressSync( - token1, - owner.publicKey, - false, - token1Program - ); - - const tx = await program.methods - .deposit(lp_token_amount, maximum_token_0_amount, maximum_token_1_amount) - .accounts({ - owner: owner.publicKey, - authority: auth, - poolState: poolAddress, - ownerLpToken, - token0Account: onwerToken0, - token1Account: onwerToken1, - token0Vault: vault0, - token1Vault: vault1, - tokenProgram: TOKEN_PROGRAM_ID, - tokenProgram2022: TOKEN_2022_PROGRAM_ID, - vault0Mint: token0, - vault1Mint: token1, - lpMint: lpMintAddress, - }) - .rpc(confirmOptions); - return tx; -} - -export async function withdraw( - program: Program, - owner: Signer, - configAddress: PublicKey, - token0: PublicKey, - token0Program: PublicKey, - token1: PublicKey, - token1Program: PublicKey, - lp_token_amount: BN, - minimum_token_0_amount: BN, - minimum_token_1_amount: BN, - confirmOptions?: ConfirmOptions -) { - const [auth] = await getAuthAddress(program.programId); - const [poolAddress] = await getPoolAddress( - configAddress, - token0, - token1, - program.programId - ); - - const [lpMintAddress] = await getPoolLpMintAddress( - poolAddress, - program.programId - ); - const [vault0] = await getPoolVaultAddress( - poolAddress, - token0, - program.programId - ); - const [vault1] = await getPoolVaultAddress( - poolAddress, - token1, - program.programId - ); - const [ownerLpToken] = await PublicKey.findProgramAddress( - [ - owner.publicKey.toBuffer(), - TOKEN_PROGRAM_ID.toBuffer(), - lpMintAddress.toBuffer(), - ], - ASSOCIATED_PROGRAM_ID - ); - - const onwerToken0 = getAssociatedTokenAddressSync( - token0, - owner.publicKey, - false, - token0Program - ); - const onwerToken1 = getAssociatedTokenAddressSync( - token1, - owner.publicKey, - false, - token1Program - ); - - const tx = await program.methods - .withdraw(lp_token_amount, minimum_token_0_amount, minimum_token_1_amount) - .accounts({ - owner: owner.publicKey, - authority: auth, - poolState: poolAddress, - ownerLpToken, - token0Account: onwerToken0, - token1Account: onwerToken1, - token0Vault: vault0, - token1Vault: vault1, - tokenProgram: TOKEN_PROGRAM_ID, - tokenProgram2022: TOKEN_2022_PROGRAM_ID, - vault0Mint: token0, - vault1Mint: token1, - lpMint: lpMintAddress, - memoProgram: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), - }) - .rpc(confirmOptions) - .catch(); - - return tx; -} - -export async function swap_base_input( - program: Program, - owner: Signer, - configAddress: PublicKey, - inputToken: PublicKey, - inputTokenProgram: PublicKey, - outputToken: PublicKey, - outputTokenProgram: PublicKey, - amount_in: BN, - minimum_amount_out: BN, - confirmOptions?: ConfirmOptions -) { - const [auth] = await getAuthAddress(program.programId); - const [poolAddress] = await getPoolAddress( - configAddress, - inputToken, - outputToken, - program.programId - ); - - const [inputVault] = await getPoolVaultAddress( - poolAddress, - inputToken, - program.programId - ); - const [outputVault] = await getPoolVaultAddress( - poolAddress, - outputToken, - program.programId - ); - - const inputTokenAccount = getAssociatedTokenAddressSync( - inputToken, - owner.publicKey, - false, - inputTokenProgram - ); - const outputTokenAccount = getAssociatedTokenAddressSync( - outputToken, - owner.publicKey, - false, - outputTokenProgram - ); - const [observationAddress] = await getOrcleAccountAddress( - poolAddress, - program.programId - ); - - const tx = await program.methods - .swapBaseInput(amount_in, minimum_amount_out) - .accounts({ - payer: owner.publicKey, - authority: auth, - ammConfig: configAddress, - poolState: poolAddress, - inputTokenAccount, - outputTokenAccount, - inputVault, - outputVault, - inputTokenProgram: inputTokenProgram, - outputTokenProgram: outputTokenProgram, - inputTokenMint: inputToken, - outputTokenMint: outputToken, - observationState: observationAddress, - }) - .rpc(confirmOptions); - - return tx; -} - -export async function swap_base_output( - program: Program, - owner: Signer, - configAddress: PublicKey, - inputToken: PublicKey, - inputTokenProgram: PublicKey, - outputToken: PublicKey, - outputTokenProgram: PublicKey, - amount_out_less_fee: BN, - max_amount_in: BN, - confirmOptions?: ConfirmOptions -) { - const [auth] = await getAuthAddress(program.programId); - const [poolAddress] = await getPoolAddress( - configAddress, - inputToken, - outputToken, - program.programId - ); - - const [inputVault] = await getPoolVaultAddress( - poolAddress, - inputToken, - program.programId - ); - const [outputVault] = await getPoolVaultAddress( - poolAddress, - outputToken, - program.programId - ); - - const inputTokenAccount = getAssociatedTokenAddressSync( - inputToken, - owner.publicKey, - false, - inputTokenProgram - ); - const outputTokenAccount = getAssociatedTokenAddressSync( - outputToken, - owner.publicKey, - false, - outputTokenProgram - ); - const [observationAddress] = await getOrcleAccountAddress( - poolAddress, - program.programId - ); - - const tx = await program.methods - .swapBaseOutput(max_amount_in, amount_out_less_fee) - .accounts({ - payer: owner.publicKey, - authority: auth, - ammConfig: configAddress, - poolState: poolAddress, - inputTokenAccount, - outputTokenAccount, - inputVault, - outputVault, - inputTokenProgram: inputTokenProgram, - outputTokenProgram: outputTokenProgram, - inputTokenMint: inputToken, - outputTokenMint: outputToken, - observationState: observationAddress, - }) - .rpc(confirmOptions); - - return tx; -} diff --git a/tests/utils/pda.ts b/tests/utils/pda.ts deleted file mode 100644 index 094089d..0000000 --- a/tests/utils/pda.ts +++ /dev/null @@ -1,127 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { PublicKey } from "@solana/web3.js"; -export const AMM_CONFIG_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("amm_config") -); -export const POOL_SEED = Buffer.from(anchor.utils.bytes.utf8.encode("pool")); -export const POOL_VAULT_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("pool_vault") -); -export const POOL_AUTH_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("vault_and_lp_mint_auth_seed") -); -export const POOL_LPMINT_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("pool_lp_mint") -); -export const TICK_ARRAY_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("tick_array") -); - -export const OPERATION_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("operation") -); - -export const ORACLE_SEED = Buffer.from( - anchor.utils.bytes.utf8.encode("observation") -); - -export function u16ToBytes(num: number) { - const arr = new ArrayBuffer(2); - const view = new DataView(arr); - view.setUint16(0, num, false); - return new Uint8Array(arr); -} - -export function i16ToBytes(num: number) { - const arr = new ArrayBuffer(2); - const view = new DataView(arr); - view.setInt16(0, num, false); - return new Uint8Array(arr); -} - -export function u32ToBytes(num: number) { - const arr = new ArrayBuffer(4); - const view = new DataView(arr); - view.setUint32(0, num, false); - return new Uint8Array(arr); -} - -export function i32ToBytes(num: number) { - const arr = new ArrayBuffer(4); - const view = new DataView(arr); - view.setInt32(0, num, false); - return new Uint8Array(arr); -} - -export async function getAmmConfigAddress( - index: number, - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [AMM_CONFIG_SEED, u16ToBytes(index)], - programId - ); - return [address, bump]; -} - -export async function getAuthAddress( - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [POOL_AUTH_SEED], - programId - ); - return [address, bump]; -} - -export async function getPoolAddress( - ammConfig: PublicKey, - tokenMint0: PublicKey, - tokenMint1: PublicKey, - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [ - POOL_SEED, - ammConfig.toBuffer(), - tokenMint0.toBuffer(), - tokenMint1.toBuffer(), - ], - programId - ); - return [address, bump]; -} - -export async function getPoolVaultAddress( - pool: PublicKey, - vaultTokenMint: PublicKey, - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [POOL_VAULT_SEED, pool.toBuffer(), vaultTokenMint.toBuffer()], - programId - ); - return [address, bump]; -} - -export async function getPoolLpMintAddress( - pool: PublicKey, - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [POOL_LPMINT_SEED, pool.toBuffer()], - programId - ); - return [address, bump]; -} - -export async function getOrcleAccountAddress( - pool: PublicKey, - programId: PublicKey -): Promise<[PublicKey, number]> { - const [address, bump] = await PublicKey.findProgramAddress( - [ORACLE_SEED, pool.toBuffer()], - programId - ); - return [address, bump]; -} diff --git a/tests/utils/util.ts b/tests/utils/util.ts deleted file mode 100644 index a58c233..0000000 --- a/tests/utils/util.ts +++ /dev/null @@ -1,279 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { web3 } from "@coral-xyz/anchor"; -import { - Connection, - PublicKey, - Keypair, - Signer, - TransactionInstruction, - SystemProgram, - Transaction, - sendAndConfirmTransaction, -} from "@solana/web3.js"; -import { - createMint, - TOKEN_PROGRAM_ID, - getOrCreateAssociatedTokenAccount, - mintTo, - TOKEN_2022_PROGRAM_ID, - getAssociatedTokenAddressSync, - ExtensionType, - getMintLen, - createInitializeTransferFeeConfigInstruction, - createInitializeMintInstruction, - getAccount, -} from "@solana/spl-token"; -import { sendTransaction } from "./index"; - -// create a token mint and a token2022 mint with transferFeeConfig -export async function createTokenMintAndAssociatedTokenAccount( - connection: Connection, - payer: Signer, - mintAuthority: Signer, - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number } -) { - let ixs: TransactionInstruction[] = []; - ixs.push( - web3.SystemProgram.transfer({ - fromPubkey: payer.publicKey, - toPubkey: mintAuthority.publicKey, - lamports: web3.LAMPORTS_PER_SOL, - }) - ); - await sendTransaction(connection, ixs, [payer]); - - interface Token { - address: PublicKey; - program: PublicKey; - } - - let tokenArray: Token[] = []; - let token0 = await createMint( - connection, - mintAuthority, - mintAuthority.publicKey, - null, - 9 - ); - tokenArray.push({ address: token0, program: TOKEN_PROGRAM_ID }); - - let token1 = await createMintWithTransferFee( - connection, - payer, - mintAuthority, - Keypair.generate(), - transferFeeConfig - ); - - tokenArray.push({ address: token1, program: TOKEN_2022_PROGRAM_ID }); - - tokenArray.sort(function (x, y) { - const buffer1 = x.address.toBuffer(); - const buffer2 = y.address.toBuffer(); - - for (let i = 0; i < buffer1.length && i < buffer2.length; i++) { - if (buffer1[i] < buffer2[i]) { - return -1; - } - if (buffer1[i] > buffer2[i]) { - return 1; - } - } - - if (buffer1.length < buffer2.length) { - return -1; - } - if (buffer1.length > buffer2.length) { - return 1; - } - - return 0; - }); - - token0 = tokenArray[0].address; - token1 = tokenArray[1].address; - // console.log("Token 0", token0.toString()); - // console.log("Token 1", token1.toString()); - const token0Program = tokenArray[0].program; - const token1Program = tokenArray[1].program; - - const ownerToken0Account = await getOrCreateAssociatedTokenAccount( - connection, - payer, - token0, - payer.publicKey, - false, - "processed", - { skipPreflight: true }, - token0Program - ); - - await mintTo( - connection, - payer, - token0, - ownerToken0Account.address, - mintAuthority, - 100_000_000_000_000, - [], - { skipPreflight: true }, - token0Program - ); - - // console.log( - // "ownerToken0Account key: ", - // ownerToken0Account.address.toString() - // ); - - const ownerToken1Account = await getOrCreateAssociatedTokenAccount( - connection, - payer, - token1, - payer.publicKey, - false, - "processed", - { skipPreflight: true }, - token1Program - ); - // console.log( - // "ownerToken1Account key: ", - // ownerToken1Account.address.toString() - // ); - await mintTo( - connection, - payer, - token1, - ownerToken1Account.address, - mintAuthority, - 100_000_000_000_000, - [], - { skipPreflight: true }, - token1Program - ); - - return [ - { token0, token0Program }, - { token1, token1Program }, - ]; -} - -async function createMintWithTransferFee( - connection: Connection, - payer: Signer, - mintAuthority: Signer, - mintKeypair = Keypair.generate(), - transferFeeConfig: { transferFeeBasisPoints: number; MaxFee: number } -) { - const transferFeeConfigAuthority = Keypair.generate(); - const withdrawWithheldAuthority = Keypair.generate(); - - const extensions = [ExtensionType.TransferFeeConfig]; - - const mintLen = getMintLen(extensions); - const decimals = 9; - - const mintLamports = await connection.getMinimumBalanceForRentExemption( - mintLen - ); - const mintTransaction = new Transaction().add( - SystemProgram.createAccount({ - fromPubkey: payer.publicKey, - newAccountPubkey: mintKeypair.publicKey, - space: mintLen, - lamports: mintLamports, - programId: TOKEN_2022_PROGRAM_ID, - }), - createInitializeTransferFeeConfigInstruction( - mintKeypair.publicKey, - transferFeeConfigAuthority.publicKey, - withdrawWithheldAuthority.publicKey, - transferFeeConfig.transferFeeBasisPoints, - BigInt(transferFeeConfig.MaxFee), - TOKEN_2022_PROGRAM_ID - ), - createInitializeMintInstruction( - mintKeypair.publicKey, - decimals, - mintAuthority.publicKey, - null, - TOKEN_2022_PROGRAM_ID - ) - ); - await sendAndConfirmTransaction( - connection, - mintTransaction, - [payer, mintKeypair], - undefined - ); - - return mintKeypair.publicKey; -} - -export async function getUserAndPoolVaultAmount( - owner: PublicKey, - token0Mint: PublicKey, - token0Program: PublicKey, - token1Mint: PublicKey, - token1Program: PublicKey, - poolToken0Vault: PublicKey, - poolToken1Vault: PublicKey -) { - const onwerToken0AccountAddr = getAssociatedTokenAddressSync( - token0Mint, - owner, - false, - token0Program - ); - - const onwerToken1AccountAddr = getAssociatedTokenAddressSync( - token1Mint, - owner, - false, - token1Program - ); - - const onwerToken0Account = await getAccount( - anchor.getProvider().connection, - onwerToken0AccountAddr, - "processed", - token0Program - ); - - const onwerToken1Account = await getAccount( - anchor.getProvider().connection, - onwerToken1AccountAddr, - "processed", - token1Program - ); - - const poolVault0TokenAccount = await getAccount( - anchor.getProvider().connection, - poolToken0Vault, - "processed", - token0Program - ); - - const poolVault1TokenAccount = await getAccount( - anchor.getProvider().connection, - poolToken1Vault, - "processed", - token1Program - ); - return { - onwerToken0Account, - onwerToken1Account, - poolVault0TokenAccount, - poolVault1TokenAccount, - }; -} - -export function isEqual(amount1: bigint, amount2: bigint) { - if ( - BigInt(amount1) === BigInt(amount2) || - BigInt(amount1) - BigInt(amount2) === BigInt(1) || - BigInt(amount1) - BigInt(amount2) === BigInt(-1) - ) { - return true; - } - return false; -} diff --git a/tests/utils/web3.ts b/tests/utils/web3.ts deleted file mode 100644 index 73b53de..0000000 --- a/tests/utils/web3.ts +++ /dev/null @@ -1,65 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { - Connection, - Signer, - Transaction, - TransactionInstruction, - TransactionSignature, - ConfirmOptions, -} from "@solana/web3.js"; - -export async function accountExist( - connection: anchor.web3.Connection, - account: anchor.web3.PublicKey -) { - const info = await connection.getAccountInfo(account); - if (info == null || info.data.length == 0) { - return false; - } - return true; -} - -export async function sendTransaction( - connection: Connection, - ixs: TransactionInstruction[], - signers: Array, - options?: ConfirmOptions -): Promise { - const tx = new Transaction(); - for (var i = 0; i < ixs.length; i++) { - tx.add(ixs[i]); - } - - if (options == undefined) { - options = { - preflightCommitment: "confirmed", - commitment: "confirmed", - }; - } - - const sendOpt = options && { - skipPreflight: options.skipPreflight, - preflightCommitment: options.preflightCommitment || options.commitment, - }; - - tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash; - const signature = await connection.sendTransaction(tx, signers, sendOpt); - - const status = ( - await connection.confirmTransaction(signature, options.commitment) - ).value; - - if (status.err) { - throw new Error( - `Raw transaction ${signature} failed (${JSON.stringify(status)})` - ); - } - return signature; -} - -export async function getBlockTimestamp( - connection: Connection -): Promise { - let slot = await connection.getSlot(); - return await connection.getBlockTime(slot); -} diff --git a/tests/withdraw.test.ts b/tests/withdraw.test.ts deleted file mode 100644 index c530d87..0000000 --- a/tests/withdraw.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -import * as anchor from "@coral-xyz/anchor"; -import { Program, BN } from "@coral-xyz/anchor"; -import { RaydiumCpSwap } from "../target/types/raydium_cp_swap"; -import { - deposit, - getUserAndPoolVaultAmount, - isEqual, - setupDepositTest, - withdraw, -} from "./utils"; -import { assert } from "chai"; - -describe("withdraw test", () => { - anchor.setProvider(anchor.AnchorProvider.env()); - const owner = anchor.Wallet.local().payer; - const program = anchor.workspace.RaydiumCpSwap as Program; - - const confirmOptions = { - skipPreflight: true, - }; - - it("withdraw half of lp ", async () => { - const { poolAddress, poolState } = await setupDepositTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 } - ); - const liquidity = new BN(10000000000); - await deposit( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity, - new BN(10000000000), - new BN(20000000000) - ); - - await withdraw( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity.divn(2), - new BN(10000000), - new BN(1000000), - confirmOptions - ); - const newPoolState = await program.account.poolState.fetch(poolAddress); - assert(newPoolState.lpSupply.eq(liquidity.divn(2).add(poolState.lpSupply))); - }); - - it("withdraw all lp ", async () => { - const { poolAddress, poolState } = await setupDepositTest( - program, - anchor.getProvider().connection, - owner, - { - config_index: 0, - tradeFeeRate: new BN(10), - protocolFeeRate: new BN(1000), - fundFeeRate: new BN(25000), - create_fee: new BN(0), - }, - { transferFeeBasisPoints: 0, MaxFee: 0 } - ); - const liquidity = new BN(10000000000); - const { - onwerToken0Account: ownerToken0AccountBefore, - onwerToken1Account: ownerToken1AccountBefore, - poolVault0TokenAccount: poolVault0TokenAccountBefore, - poolVault1TokenAccount: poolVault1TokenAccountBefore, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - - await deposit( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity, - new BN(10000000000), - new BN(20000000000) - ); - - await withdraw( - program, - owner, - poolState.ammConfig, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - liquidity, - new BN(10000000), - new BN(1000000), - confirmOptions - ); - - const newPoolState = await program.account.poolState.fetch(poolAddress); - assert(newPoolState.lpSupply.eq(poolState.lpSupply)); - - const { - onwerToken0Account: ownerToken0AccountAfter, - onwerToken1Account: ownerToken1AccountAfter, - poolVault0TokenAccount: poolVault0TokenAccountAfter, - poolVault1TokenAccount: poolVault1TokenAccountAfter, - } = await getUserAndPoolVaultAmount( - owner.publicKey, - poolState.token0Mint, - poolState.token0Program, - poolState.token1Mint, - poolState.token1Program, - poolState.token0Vault, - poolState.token1Vault - ); - - assert( - isEqual(ownerToken0AccountBefore.amount, ownerToken0AccountAfter.amount) - ); - assert( - isEqual(ownerToken1AccountBefore.amount, ownerToken1AccountAfter.amount) - ); - assert( - isEqual( - poolVault0TokenAccountBefore.amount, - poolVault0TokenAccountAfter.amount - ) - ); - assert( - isEqual( - poolVault1TokenAccountBefore.amount, - poolVault1TokenAccountAfter.amount - ) - ); - }); -}); diff --git a/yarn.lock b/yarn.lock index 17fa4be..f5ed182 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,18 +7,18 @@ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6" integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q== -"@coral-xyz/anchor-errors@^0.31.0": +"@coral-xyz/anchor-errors@^0.31.1": version "0.31.1" resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.31.1.tgz#d635cbac2533973ae6bfb5d3ba1de89ce5aece2d" integrity sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ== -"@coral-xyz/anchor@0.31.0": - version "0.31.0" - resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.0.tgz#76b84541e6fdfbd6c661584cdc418453a6416f12" - integrity sha512-Yb1NwP1s4cWhAw7wL7vOLHSWWw3cD5D9pRCVSeJpdqPaI+w7sfRLScnVJL6ViYMZynB7nAG/5HcUPKUnY0L9rw== +"@coral-xyz/anchor@0.31.1": + version "0.31.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.31.1.tgz#0fdeebf45a3cb2e47e8ebbb815ca98542152962c" + integrity sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA== dependencies: - "@coral-xyz/anchor-errors" "^0.31.0" - "@coral-xyz/borsh" "^0.31.0" + "@coral-xyz/anchor-errors" "^0.31.1" + "@coral-xyz/borsh" "^0.31.1" "@noble/hashes" "^1.3.1" "@solana/web3.js" "^1.69.0" bn.js "^5.1.2" @@ -31,7 +31,15 @@ superstruct "^0.15.4" toml "^3.0.0" -"@coral-xyz/borsh@^0.31.0": +"@coral-xyz/borsh@^0.29.0": + version "0.29.0" + resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.29.0.tgz#79f7045df2ef66da8006d47f5399c7190363e71f" + integrity sha512-s7VFVa3a0oqpkuRloWVPdCK7hMbAMY270geZOGfCnaqexrP5dTIpbEHL33req6IYPPJ0hYa71cdvJ1h6V55/oQ== + dependencies: + bn.js "^5.1.2" + buffer-layout "^1.2.0" + +"@coral-xyz/borsh@^0.31.1": version "0.31.1" resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.31.1.tgz#5328e1e0921b75d7f4a62dd3f61885a938bc7241" integrity sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw== @@ -39,6 +47,30 @@ bn.js "^5.1.2" buffer-layout "^1.2.0" +"@lightprotocol/compressed-token@0.22.1-alpha.0": + version "0.22.1-alpha.0" + resolved "https://registry.yarnpkg.com/@lightprotocol/compressed-token/-/compressed-token-0.22.1-alpha.0.tgz#3ce080bf07f916bbee05644a9e380374a564fc81" + integrity sha512-MNJ4hcWelFqtKiqyUbSdod3qE/TDyiWqCp3vgkTxK65t4HQOmdMmKmB97DXN4vWKdA3N045SIt1WtYIoZWMbnQ== + dependencies: + "@coral-xyz/borsh" "^0.29.0" + bn.js "^5.2.1" + buffer "6.0.3" + +"@lightprotocol/stateless.js@0.22.1-alpha.0": + version "0.22.1-alpha.0" + resolved "https://registry.yarnpkg.com/@lightprotocol/stateless.js/-/stateless.js-0.22.1-alpha.0.tgz#a603723e0bdd0ee3189e084a0ca9cc220b1245d6" + integrity sha512-w8Jy+wv2T8vdkvjwFT7bObsHiNOsOeCxR9fGYNBBSojp1jBQPOWG9no7/Kdhf24TV61tLhFXWuFKG0ipxpevag== + dependencies: + "@coral-xyz/borsh" "^0.29.0" + "@noble/hashes" "1.5.0" + bn.js "^5.2.1" + bs58 "^6.0.0" + buffer "6.0.3" + buffer-layout "^1.2.2" + camelcase "^8.0.0" + camelcase-keys "^9.1.3" + superstruct "2.0.2" + "@noble/curves@^1.4.2": version "1.9.3" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.3.tgz#822c61359875a4d3bfdacaa724ceca6c5e6708c3" @@ -46,7 +78,12 @@ dependencies: "@noble/hashes" "1.8.0" -"@noble/hashes@1.8.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0": +"@noble/hashes@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== + +"@noble/hashes@1.8.0", "@noble/hashes@^1.3.1", "@noble/hashes@^1.4.0", "@noble/hashes@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== @@ -331,6 +368,11 @@ base-x@^3.0.2: dependencies: safe-buffer "^5.0.1" +base-x@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-5.0.1.tgz#16bf35254be1df8aca15e36b7c1dda74b2aa6b03" + integrity sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg== + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -401,6 +443,13 @@ bs58@^4.0.0, bs58@^4.0.1: dependencies: base-x "^3.0.2" +bs58@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-6.0.0.tgz#a2cda0130558535dd281a2f8697df79caaf425d8" + integrity sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw== + dependencies: + base-x "^5.0.0" + buffer-from@^1.0.0, buffer-from@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -426,11 +475,26 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.3.0" +camelcase-keys@^9.1.3: + version "9.1.3" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-9.1.3.tgz#6367b2f9ec5724af541f58f0dcfee9b200022e5c" + integrity sha512-Rircqi9ch8AnZscQcsA1C47NFdaO3wukpmIRzYcDOrmvgt78hM/sj5pZhZNec2NM12uk5vTwRHZ4anGcrC4ZTg== + dependencies: + camelcase "^8.0.0" + map-obj "5.0.0" + quick-lru "^6.1.1" + type-fest "^4.3.2" + camelcase@^6.0.0, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelcase@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-8.0.0.tgz#c0d36d418753fb6ad9c5e0437579745c1c14a534" + integrity sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA== + chai@^4.3.4: version "4.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" @@ -825,6 +889,11 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +map-obj@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-5.0.0.tgz#126c98596b63927d7360f287cccc67177aa1938b" + integrity sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA== + minimatch@4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-4.2.1.tgz#40d9d511a46bdc4e563c22c3080cde9c0d8299b4" @@ -964,6 +1033,11 @@ prettier@^2.6.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +quick-lru@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-6.1.2.tgz#e9a90524108629be35287d0b864e7ad6ceb3659e" + integrity sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -1062,16 +1136,16 @@ strip-json-comments@3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +superstruct@2.0.2, superstruct@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" + integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== + superstruct@^0.15.4: version "0.15.5" resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.15.5.tgz#0f0a8d3ce31313f0d84c6096cd4fa1bfdedc9dab" integrity sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ== -superstruct@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-2.0.2.tgz#3f6d32fbdc11c357deff127d591a39b996300c54" - integrity sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A== - supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" @@ -1151,6 +1225,11 @@ type-detect@^4.0.0, type-detect@^4.1.0: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== +type-fest@^4.3.2: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + typescript@^4.3.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"