diff --git a/p-ata/.vscode/settings.json b/p-ata/.vscode/settings.json new file mode 100644 index 00000000..1d5a6efa --- /dev/null +++ b/p-ata/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "rust-analyzer.cargo.features": ["std"], + "rust-analyzer.cargo.allFeatures": false +} \ No newline at end of file diff --git a/p-ata/Cargo.lock b/p-ata/Cargo.lock new file mode 100644 index 00000000..d24628bc --- /dev/null +++ b/p-ata/Cargo.lock @@ -0,0 +1,7390 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "agave-feature-set" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e4bb8842e634f00f7f56bed7fcf67464bf2689378b3977350a8d0e6918a1ea" +dependencies = [ + "ahash", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", + "solana-svm-feature-set 2.3.6", +] + +[[package]] +name = "agave-feature-set" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "ahash", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", + "solana-svm-feature-set 3.0.0", +] + +[[package]] +name = "agave-feature-set" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c12c927bcda6aa2b42a1b586cde001725c557c181cf1be7d270821a9b160630e" +dependencies = [ + "ahash", + "solana-epoch-schedule 3.0.0", + "solana-hash 3.0.0", + "solana-pubkey 3.0.0", + "solana-sha256-hasher 3.0.0", + "solana-svm-feature-set 3.0.3", +] + +[[package]] +name = "agave-precompiles" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "agave-feature-set 3.0.0", + "bincode", + "digest 0.10.7", + "ed25519-dalek 1.0.1", + "libsecp256k1", + "openssl", + "sha3", + "solana-ed25519-program 2.2.3", + "solana-message 2.4.0", + "solana-precompile-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-secp256k1-program 2.2.3", + "solana-secp256r1-program 2.2.4", +] + +[[package]] +name = "agave-precompiles" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b091db77eedde2a22abcb6d5bbbe8cef3510ddd4987cbbbcc124196fd6cf9a47" +dependencies = [ + "agave-feature-set 3.0.3", + "bincode", + "digest 0.10.7", + "ed25519-dalek 1.0.1", + "libsecp256k1", + "openssl", + "sha3", + "solana-ed25519-program 3.0.0", + "solana-message 3.0.1", + "solana-precompile-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-secp256k1-program 3.0.0", + "solana-secp256r1-program 3.0.0", +] + +[[package]] +name = "agave-syscalls" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142b9c5d9844a44c1e0329ff0b84be3de3f425758b53f76d33d2362cd0d7056f" +dependencies = [ + "bincode", + "libsecp256k1", + "num-traits", + "solana-account 3.0.0", + "solana-account-info 3.0.0", + "solana-big-mod-exp 3.0.0", + "solana-blake3-hasher 3.0.0", + "solana-bn254 3.0.0", + "solana-clock 3.0.0", + "solana-cpi 3.0.0", + "solana-curve25519 3.0.3", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-keccak-hasher 3.0.0", + "solana-loader-v3-interface 6.1.0", + "solana-poseidon 3.0.3", + "solana-program-entrypoint 3.1.0", + "solana-program-runtime 3.0.3", + "solana-pubkey 3.0.0", + "solana-sbpf 0.12.2", + "solana-sdk-ids 3.0.0", + "solana-secp256k1-recover 3.0.0", + "solana-sha256-hasher 3.0.0", + "solana-stable-layout 3.0.0", + "solana-stake-interface 2.0.1", + "solana-svm-callback 3.0.3", + "solana-svm-feature-set 3.0.3", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-timings", + "solana-svm-type-overrides", + "solana-sysvar 3.0.0", + "solana-sysvar-id 3.0.0", + "solana-transaction-context 3.0.3", + "thiserror 2.0.16", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "async-compression" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "ata-mollusk-harness" +version = "1.0.0" +dependencies = [ + "mollusk-svm 0.6.1", + "mollusk-svm-programs-token", + "solana-account 3.0.0", + "solana-instruction 3.0.0", + "solana-keypair 3.0.1", + "solana-program-error 3.0.0", + "solana-program-option 3.0.0", + "solana-program-pack 3.0.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "solana-signer 3.0.0", + "solana-system-interface 2.0.0", + "solana-sysvar 3.0.0", + "spl-associated-token-account-interface", + "spl-token-2022-interface", + "spl-token-interface 2.0.0", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +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 = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +dependencies = [ + "serde", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +dependencies = [ + "borsh-derive 1.5.7", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +dependencies = [ + "once_cell", + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "brotli" +version = "8.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cfg_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "num-traits", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.104", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "eager" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.2.0", + "spki", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", + "rand_core 0.6.4", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", +] + +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek 1.0.1", + "hmac 0.12.1", + "sha2 0.10.9", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" + +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "humantime" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.0", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.4", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +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", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.9", + "signature 2.2.0", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "mollusk-svm" +version = "0.4.1" +source = "git+https://github.com/rustopian/mollusk.git?branch=rustopian%2Fcreate-prefunded-account#257dbfc3b2132112f02c23458167cdc9aa5f9c3d" +dependencies = [ + "agave-feature-set 3.0.0", + "agave-precompiles 3.0.0", + "bincode", + "mollusk-svm-error 0.4.1", + "mollusk-svm-keys 0.4.1", + "mollusk-svm-result 0.4.1", + "solana-account 2.2.1", + "solana-bpf-loader-program 3.0.0", + "solana-clock 2.2.2", + "solana-compute-budget 3.0.0", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-loader-v3-interface 3.0.0", + "solana-loader-v4-interface 2.2.1", + "solana-log-collector 3.0.0", + "solana-logger 2.3.1", + "solana-precompile-error 2.2.2", + "solana-program-error 2.2.2", + "solana-program-runtime 3.0.0", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-stake-interface 1.2.1", + "solana-stake-program", + "solana-svm-callback 3.0.0", + "solana-system-program", + "solana-sysvar 2.2.2", + "solana-sysvar-id 2.2.1", + "solana-timings 3.0.0", + "solana-transaction-context 3.0.0", +] + +[[package]] +name = "mollusk-svm" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7da80022acbada517ec6becc3e7e2012b9012e1cf00cf0e0a336156f32fddd" +dependencies = [ + "agave-feature-set 3.0.3", + "agave-precompiles 3.0.3", + "agave-syscalls", + "bincode", + "mollusk-svm-error 0.6.1", + "mollusk-svm-keys 0.6.1", + "mollusk-svm-result 0.6.1", + "solana-account 3.0.0", + "solana-bpf-loader-program 3.0.3", + "solana-clock 3.0.0", + "solana-compute-budget 3.0.3", + "solana-epoch-rewards 3.0.0", + "solana-epoch-schedule 3.0.0", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-instruction-error", + "solana-loader-v3-interface 6.1.0", + "solana-loader-v4-interface 3.1.0", + "solana-logger 3.0.0", + "solana-precompile-error 3.0.0", + "solana-program-error 3.0.0", + "solana-program-runtime 3.0.3", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-slot-hashes 3.0.0", + "solana-stake-interface 2.0.1", + "solana-svm-callback 3.0.3", + "solana-svm-log-collector", + "solana-svm-timings", + "solana-system-program", + "solana-sysvar 3.0.0", + "solana-sysvar-id 3.0.0", + "solana-transaction-context 3.0.3", +] + +[[package]] +name = "mollusk-svm-error" +version = "0.4.1" +source = "git+https://github.com/rustopian/mollusk.git?branch=rustopian%2Fcreate-prefunded-account#257dbfc3b2132112f02c23458167cdc9aa5f9c3d" +dependencies = [ + "solana-pubkey 2.4.0", + "thiserror 1.0.69", +] + +[[package]] +name = "mollusk-svm-error" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97230bc9e87c95fcd9cc0b42a9da212e9a62b0807b70cadfcf9272baef8900bd" +dependencies = [ + "solana-pubkey 3.0.0", + "thiserror 1.0.69", +] + +[[package]] +name = "mollusk-svm-keys" +version = "0.4.1" +source = "git+https://github.com/rustopian/mollusk.git?branch=rustopian%2Fcreate-prefunded-account#257dbfc3b2132112f02c23458167cdc9aa5f9c3d" +dependencies = [ + "mollusk-svm-error 0.4.1", + "solana-account 2.2.1", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-transaction-context 3.0.0", +] + +[[package]] +name = "mollusk-svm-keys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11a5b42ac2953ef03b105388cbef6e35a1b2ef05277f9bc7c4c8c5dfe2dbae85" +dependencies = [ + "mollusk-svm-error 0.6.1", + "solana-account 3.0.0", + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", + "solana-transaction-context 3.0.3", +] + +[[package]] +name = "mollusk-svm-programs-token" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a7e8c32a28672340d54b7b0c4887e755ede53e86dfff09d80e7c62153c43483" +dependencies = [ + "mollusk-svm 0.6.1", + "solana-account 3.0.0", + "solana-program-pack 3.0.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "spl-associated-token-account-interface", + "spl-token-interface 2.0.0", +] + +[[package]] +name = "mollusk-svm-result" +version = "0.4.1" +source = "git+https://github.com/rustopian/mollusk.git?branch=rustopian%2Fcreate-prefunded-account#257dbfc3b2132112f02c23458167cdc9aa5f9c3d" +dependencies = [ + "solana-account 2.2.1", + "solana-instruction 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", +] + +[[package]] +name = "mollusk-svm-result" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7645fffe38e8de4831bebbe94db7d96d05c056b400aa7a1d9c3c1224ae0e592c" +dependencies = [ + "solana-account 3.0.0", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", +] + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "openssl-src" +version = "300.5.1+3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "735230c832b28c000e3bc117119e6466a663ec73506bc0a9907ea4187508e42a" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pinocchio" +version = "0.9.2" +source = "git+https://github.com/rustopian/pinocchio.git?branch=create-prefunded-account#5a7bfd14d528baffd66e24865e2eaddd645754e7" + +[[package]] +name = "pinocchio-ata-program" +version = "0.1.0" +dependencies = [ + "ata-mollusk-harness", + "curve25519-dalek 4.1.3", + "mollusk-svm 0.4.1", + "pinocchio", + "pinocchio-log", + "pinocchio-pubkey", + "pinocchio-system", + "serde_json", + "solana-keypair 2.2.3", + "solana-program", + "solana-pubkey 2.4.0", + "solana-sdk", + "solana-sdk-ids 2.2.1", + "solana-signer 2.2.1", + "spl-associated-token-account", + "spl-token", + "spl-token-2022", + "spl-token-group-interface 0.6.0", + "spl-token-interface 0.0.0", + "spl-token-metadata-interface 0.7.0", +] + +[[package]] +name = "pinocchio-log" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89f8ffd986174cefe59448295a004aaf70c3605f30de066f42d27b06188f267" +dependencies = [ + "pinocchio-log-macro", +] + +[[package]] +name = "pinocchio-log-macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edac6ac2c9c456b850d3e908b7f224a54623f6c5b75906b9e48a4e248fb332b" +dependencies = [ + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "pinocchio-pubkey" +version = "0.3.0" +source = "git+https://github.com/rustopian/pinocchio.git?branch=create-prefunded-account#5a7bfd14d528baffd66e24865e2eaddd645754e7" +dependencies = [ + "five8_const", + "pinocchio", + "sha2-const-stable", +] + +[[package]] +name = "pinocchio-system" +version = "0.3.0" +source = "git+https://github.com/rustopian/pinocchio.git?branch=create-prefunded-account#5a7bfd14d528baffd66e24865e2eaddd645754e7" +dependencies = [ + "pinocchio", + "pinocchio-pubkey", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qstring" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "quinn" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.5.10", + "thiserror 2.0.16", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.16", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.10", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +dependencies = [ + "async-compression", + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "serde", + "serde_derive", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "bincode", + "qualifier_attr", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info 2.3.0", + "solana-clock 2.2.2", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-sysvar 2.2.2", +] + +[[package]] +name = "solana-account" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f885ce7f937871ecb56aadbeaaec963b234a580b7d6ebbdb8fa4249a36f92433" +dependencies = [ + "bincode", + "qualifier_attr", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info 3.0.0", + "solana-clock 3.0.0", + "solana-instruction-error", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-sysvar 3.0.0", +] + +[[package]] +name = "solana-account-info" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" +dependencies = [ + "bincode", + "serde", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-account-info" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f4691b69b172c687d218dd2f1f23fc7ea5e9aa79df9ac26dab3d8dd829ce48" +dependencies = [ + "solana-program-error 3.0.0", + "solana-program-memory 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-address" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a7a457086457ea9db9a5199d719dc8734dc2d0342fad0d8f77633c31eb62f19" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "serde", + "serde_derive", + "solana-atomic-u64 3.0.0", + "solana-define-syscall 3.0.0", + "solana-program-error 3.0.0", + "solana-sanitize 3.0.1", + "solana-sha256-hasher 3.0.0", +] + +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock 2.2.2", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-slot-hashes 2.2.1", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52e52720efe60465b052b9e7445a01c17550666beec855cce66f44766697bc2" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-atomic-u64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a933ff1e50aff72d02173cfcd7511bd8540b027ee720b75f353f594f834216d0" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "solana-define-syscall 2.3.0", +] + +[[package]] +name = "solana-big-mod-exp" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c80fb6d791b3925d5ec4bf23a7c169ef5090c013059ec3ed7d0b2c04efa085" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction 2.3.0", +] + +[[package]] +name = "solana-bincode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534a37aecd21986089224d0c01006a75b96ac6fb2f418c24edc15baf0d2a4c99" +dependencies = [ + "bincode", + "serde", + "solana-instruction-error", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall 2.3.0", + "solana-hash 2.3.0", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-blake3-hasher" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffa2e3bdac3339c6d0423275e45dafc5ac25f4d43bf344d026a3cc9a85e244a6" +dependencies = [ + "blake3", + "solana-define-syscall 3.0.0", + "solana-hash 3.0.0", +] + +[[package]] +name = "solana-bn254" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4420f125118732833f36facf96a27e7b78314b2d642ba07fa9ffdacd8d79e243" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "bytemuck", + "solana-define-syscall 2.3.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-bn254" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20a5f01e99addb316d95d4ed31aa6eacfda557fffc00ae316b919e8ba0fc5b91" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "bytemuck", + "solana-define-syscall 3.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", +] + +[[package]] +name = "solana-borsh" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc402b16657abbfa9991cd5cbfac5a11d809f7e7d28d3bb291baeb088b39060e" +dependencies = [ + "borsh 1.5.7", +] + +[[package]] +name = "solana-bpf-loader-program" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "bincode", + "libsecp256k1", + "num-traits", + "qualifier_attr", + "scopeguard", + "solana-account 2.2.1", + "solana-account-info 2.3.0", + "solana-big-mod-exp 2.2.1", + "solana-bincode 2.2.1", + "solana-blake3-hasher 2.2.1", + "solana-bn254 2.2.2", + "solana-clock 2.2.2", + "solana-cpi 2.2.1", + "solana-curve25519 3.0.0", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-keccak-hasher 2.2.1", + "solana-loader-v3-interface 5.0.0", + "solana-loader-v4-interface 2.2.1", + "solana-log-collector 3.0.0", + "solana-measure 3.0.0", + "solana-packet 2.2.1", + "solana-poseidon 3.0.0", + "solana-program-entrypoint 2.3.0", + "solana-program-runtime 3.0.0", + "solana-pubkey 2.4.0", + "solana-sbpf 0.11.1", + "solana-sdk-ids 2.2.1", + "solana-secp256k1-recover 2.2.1", + "solana-sha256-hasher 2.3.0", + "solana-stable-layout 2.2.1", + "solana-svm-feature-set 3.0.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-sysvar-id 2.2.1", + "solana-timings 3.0.0", + "solana-transaction-context 3.0.0", + "solana-type-overrides 3.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-bpf-loader-program" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2ff8235753ca5f9a6c3b7b734c176c043f21487da3bb9b048690b3b14dd9da" +dependencies = [ + "agave-syscalls", + "bincode", + "qualifier_attr", + "solana-account 3.0.0", + "solana-bincode 3.0.0", + "solana-clock 3.0.0", + "solana-instruction 3.0.0", + "solana-loader-v3-interface 6.1.0", + "solana-loader-v4-interface 3.1.0", + "solana-packet 3.0.0", + "solana-program-entrypoint 3.1.0", + "solana-program-runtime 3.0.3", + "solana-pubkey 3.0.0", + "solana-sbpf 0.12.2", + "solana-sdk-ids 3.0.0", + "solana-svm-feature-set 3.0.3", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-type-overrides", + "solana-system-interface 2.0.0", + "solana-transaction-context 3.0.3", +] + +[[package]] +name = "solana-client-traits" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f0071874e629f29e0eb3dab8a863e98502ac7aba55b7e0df1803fc5cac72a7" +dependencies = [ + "solana-account 2.2.1", + "solana-commitment-config", + "solana-epoch-info", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction 2.2.3", + "solana-transaction-error 2.2.1", +] + +[[package]] +name = "solana-clock" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb482ab70fced82ad3d7d3d87be33d466a3498eb8aa856434ff3c0dfc2e2e31" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-clock" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb62e9381182459a4520b5fe7fb22d423cae736239a6427fc398a88743d0ed59" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-cluster-type" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ace9fea2daa28354d107ea879cff107181d85cd4e0f78a2bedb10e1a428c97e" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 2.3.0", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-compute-budget" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "solana-fee-structure 2.3.0", + "solana-program-runtime 3.0.0", +] + +[[package]] +name = "solana-compute-budget" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397dd41531fa4c789e7ce8d3a74516361cfe519d22eb1aa9e48010320ec419b2" +dependencies = [ + "solana-fee-structure 3.0.0", + "solana-program-runtime 3.0.3", +] + +[[package]] +name = "solana-compute-budget-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4" +dependencies = [ + "borsh 1.5.7", + "serde", + "serde_derive", + "solana-instruction 2.3.0", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-config-program-client" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53aceac36f105fd4922e29b4f0c1f785b69d7b3e7e387e384b8985c8e0c3595e" +dependencies = [ + "bincode", + "borsh 0.10.4", + "kaigan", + "serde", + "solana-program", +] + +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info 2.3.0", + "solana-define-syscall 2.3.0", + "solana-instruction 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-stable-layout 2.2.1", +] + +[[package]] +name = "solana-cpi" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16238feb63d1cbdf915fb287f29ef7a7ebf81469bd6214f8b72a53866b593f8f" +dependencies = [ + "solana-account-info 3.0.0", + "solana-define-syscall 3.0.0", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-stable-layout 3.0.0", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad6269c8dded5d571c75a4a32997514f57f23757f2e18549ca3040586465e336" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall 2.3.0", + "subtle", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-curve25519" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall 2.3.0", + "subtle", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-curve25519" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a066fb2de74b9abdbb807353ddbc554d1d1e03a190937556d446923b20ccad" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall 3.0.0", + "subtle", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-define-syscall" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae3e2abcf541c8122eafe9a625d4d194b4023c20adde1e251f94e056bb1aee2" + +[[package]] +name = "solana-define-syscall" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9697086a4e102d28a156b8d6b521730335d6951bd39a5e766512bbe09007cee" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-derivation-path" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff71743072690fdbdfcdc37700ae1cb77485aaad49019473a81aee099b1e0b8c" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + +[[package]] +name = "solana-ed25519-program" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feafa1691ea3ae588f99056f4bdd1293212c7ece28243d7da257c443e84753" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "ed25519-dalek 1.0.1", + "solana-feature-set", + "solana-instruction 2.3.0", + "solana-precompile-error 2.2.2", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-ed25519-program" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1419197f1c06abf760043f6d64ba9d79a03ad5a43f18c7586471937122094da" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "solana-instruction 3.0.0", + "solana-sdk-ids 3.0.0", +] + +[[package]] +name = "solana-epoch-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ef6f0b449290b0b9f32973eefd95af35b01c5c0c34c569f936c34c5b20d77b" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 2.3.0", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-epoch-rewards" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b319a4ed70390af911090c020571f0ff1f4ec432522d05ab89f5c08080381995" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-epoch-rewards-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c5fd2662ae7574810904585fd443545ed2b568dbd304b25a31e79ccc76e81b" +dependencies = [ + "siphasher", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-epoch-schedule" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5481e72cc4d52c169db73e4c0cd16de8bc943078aac587ec4817a75cc6388f" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock 2.2.2", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-keccak-hasher 2.2.1", + "solana-message 2.4.0", + "solana-nonce", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-account-info 2.3.0", + "solana-instruction 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", +] + +[[package]] +name = "solana-feature-set" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b93971e289d6425f88e6e3cb6668c4b05df78b3c518c249be55ced8efd6b6d" +dependencies = [ + "ahash", + "lazy_static", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", +] + +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-fee-calculator" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a73cc03ca4bed871ca174558108835f8323e85917bb38b9c81c7af2ab853efe" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-fee-structure" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33adf673581c38e810bf618f745bf31b683a0a4a4377682e6aaac5d9a058dd4e" +dependencies = [ + "serde", + "serde_derive", + "solana-message 2.4.0", + "solana-native-token", +] + +[[package]] +name = "solana-fee-structure" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2abdb1223eea8ec64136f39cb1ffcf257e00f915c957c35c0dd9e3f4e700b0" + +[[package]] +name = "solana-genesis-config" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3725085d47b96d37fef07a29d78d2787fc89a0b9004c66eed7753d1e554989f" +dependencies = [ + "bincode", + "chrono", + "memmap2", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-clock 2.2.2", + "solana-cluster-type", + "solana-epoch-schedule 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-inflation", + "solana-keypair 2.2.3", + "solana-logger 2.3.1", + "solana-poh-config", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sha256-hasher 2.3.0", + "solana-shred-version", + "solana-signer 2.2.1", + "solana-time-utils", +] + +[[package]] +name = "solana-hard-forks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c28371f878e2ead55611d8ba1b5fb879847156d04edea13693700ad1a28baf" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-hash" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "five8", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64 2.2.1", + "solana-sanitize 2.2.1", + "wasm-bindgen", +] + +[[package]] +name = "solana-hash" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a063723b9e84c14d8c0d2cdf0268207dc7adecf546e31251f9e07c7b00b566c" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "five8", + "serde", + "serde_derive", + "solana-atomic-u64 3.0.0", + "solana-sanitize 3.0.1", +] + +[[package]] +name = "solana-inflation" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23eef6a09eb8e568ce6839573e4966850e85e9ce71e6ae1a6c930c1c43947de3" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-instruction" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47298e2ce82876b64f71e9d13a46bc4b9056194e7f9937ad3084385befa50885" +dependencies = [ + "bincode", + "borsh 1.5.7", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-define-syscall 2.3.0", + "solana-pubkey 2.4.0", + "wasm-bindgen", +] + +[[package]] +name = "solana-instruction" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df4e8fcba01d7efa647ed20a081c234475df5e11a93acb4393cc2c9a7b99bab" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-define-syscall 3.0.0", + "solana-instruction-error", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-instruction-error" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f0d483b8ae387178d9210e0575b666b05cdd4bd0f2f188128249f6e454d39d" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-program-error 3.0.0", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags", + "solana-account-info 2.3.0", + "solana-instruction 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-serialize-utils 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ddf67876c541aa1e21ee1acae35c95c6fbc61119814bfef70579317a5e26955" +dependencies = [ + "bitflags", + "solana-account-info 3.0.0", + "solana-instruction 3.0.0", + "solana-instruction-error", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-sanitize 3.0.1", + "solana-sdk-ids 3.0.0", + "solana-serialize-utils 3.1.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall 2.3.0", + "solana-hash 2.3.0", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-keccak-hasher" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57eebd3012946913c8c1b8b43cdf8a6249edb09c0b6be3604ae910332a3acd97" +dependencies = [ + "sha3", + "solana-define-syscall 3.0.0", + "solana-hash 3.0.0", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek 1.0.1", + "ed25519-dalek-bip32", + "five8", + "rand 0.7.3", + "solana-derivation-path 2.2.1", + "solana-pubkey 2.4.0", + "solana-seed-derivable 2.2.1", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "wasm-bindgen", +] + +[[package]] +name = "solana-keypair" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "952ed9074c12edd2060cb09c2a8c664303f4ab7f7056a407ac37dd1da7bdaa3e" +dependencies = [ + "ed25519-dalek 2.2.0", + "five8", + "rand 0.8.5", + "solana-pubkey 3.0.0", + "solana-seed-phrase 3.0.0", + "solana-signature 3.1.0", + "solana-signer 3.0.0", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-last-restart-slot" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcda154ec827f5fc1e4da0af3417951b7e9b8157540f81f936c4a8b1156134d0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee44c9b1328c5c712c68966fb8de07b47f3e7bac006e74ddd1bb053d3e46e5d" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c948b33ff81fa89699911b207059e493defdba9647eaf18f23abdf3674e0fb" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-system-interface 2.0.0", +] + +[[package]] +name = "solana-log-collector" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdc85854914788b7cd377183a991ea94ed0779f0dee086f86af512f928ee07c5" +dependencies = [ + "log", +] + +[[package]] +name = "solana-log-collector" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "log", +] + +[[package]] +name = "solana-logger" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8e777ec1afd733939b532a42492d888ec7c88d8b4127a5d867eb45c6eb5cd5" +dependencies = [ + "env_logger 0.9.3", + "lazy_static", + "libc", + "log", + "signal-hook", +] + +[[package]] +name = "solana-logger" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef7421d1092680d72065edbf5c7605856719b021bf5f173656c71febcdd5d003" +dependencies = [ + "env_logger 0.11.8", + "lazy_static", + "libc", + "log", + "signal-hook", +] + +[[package]] +name = "solana-measure" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6371c5d9be72d0c88b017955123908fc720d7b16cb69919f6cd240571f4e395" + +[[package]] +name = "solana-measure" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-short-vec", + "solana-system-interface 1.0.0", + "solana-transaction-error 2.2.1", + "wasm-bindgen", +] + +[[package]] +name = "solana-message" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85666605c9fd727f865ed381665db0a8fc29f984a030ecc1e40f43bfb2541623" +dependencies = [ + "lazy_static", + "solana-address", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-sanitize 3.0.1", + "solana-sdk-ids 3.0.0", + "solana-transaction-error 3.0.0", +] + +[[package]] +name = "solana-metrics" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "crossbeam-channel", + "gethostname", + "log", + "reqwest", + "solana-cluster-type", + "solana-sha256-hasher 2.3.0", + "solana-time-utils", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall 2.3.0", +] + +[[package]] +name = "solana-msg" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "264275c556ea7e22b9d3f87d56305546a38d4eee8ec884f3b126236cb7dcbbb4" +dependencies = [ + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", +] + +[[package]] +name = "solana-nonce-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde971a20b8dbf60144d6a84439dda86b5466e00e2843091fe731083cda614da" +dependencies = [ + "solana-account 2.2.1", + "solana-hash 2.3.0", + "solana-nonce", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-offchain-message" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b526398ade5dea37f1f147ce55dae49aa017a5d7326606359b0445ca8d946581" +dependencies = [ + "num_enum", + "solana-hash 2.3.0", + "solana-packet 2.2.1", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sha256-hasher 2.3.0", + "solana-signature 2.3.0", + "solana-signer 2.2.1", +] + +[[package]] +name = "solana-packet" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "004f2d2daf407b3ec1a1ca5ec34b3ccdfd6866dd2d3c7d0715004a96e4b6d127" +dependencies = [ + "bincode", + "bitflags", + "cfg_eval", + "serde", + "serde_derive", + "serde_with", +] + +[[package]] +name = "solana-packet" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edf2f25743c95229ac0fdc32f8f5893ef738dbf332c669e9861d33ddb0f469d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "solana-poh-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d650c3b4b9060082ac6b0efbbb66865089c58405bfb45de449f3f2b91eccee75" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-poseidon" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "ark-bn254", + "light-poseidon", + "solana-define-syscall 2.3.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-poseidon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7cffa9fee28081d6f7e56734ee97ca11262d48f7894992791a3eac8a952ea4" +dependencies = [ + "ark-bn254", + "light-poseidon", + "solana-define-syscall 3.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-precompile-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d87b2c1f5de77dfe2b175ee8dd318d196aaca4d0f66f02842f80c852811f9f8" +dependencies = [ + "num-traits", + "solana-decode-error", +] + +[[package]] +name = "solana-precompile-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cafcd950de74c6c39d55dc8ca108bbb007799842ab370ef26cf45a34453c31e1" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-precompiles" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36e92768a57c652edb0f5d1b30a7d0bc64192139c517967c18600debe9ae3832" +dependencies = [ + "lazy_static", + "solana-ed25519-program 2.2.3", + "solana-feature-set", + "solana-message 2.4.0", + "solana-precompile-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-secp256k1-program 2.2.3", + "solana-secp256r1-program 2.2.4", +] + +[[package]] +name = "solana-presigner" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a57a24e6a4125fc69510b6774cd93402b943191b6cddad05de7281491c90fe" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-signature 2.3.0", + "solana-signer 2.2.1", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.5.7", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.16", + "lazy_static", + "log", + "memoffset", + "num-bigint 0.4.6", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info 2.3.0", + "solana-address-lookup-table-interface", + "solana-atomic-u64 2.2.1", + "solana-big-mod-exp 2.2.1", + "solana-bincode 2.2.1", + "solana-blake3-hasher 2.2.1", + "solana-borsh 2.2.1", + "solana-clock 2.2.2", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-define-syscall 2.3.0", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-instructions-sysvar 2.2.2", + "solana-keccak-hasher 2.2.1", + "solana-last-restart-slot 2.2.1", + "solana-loader-v2-interface", + "solana-loader-v3-interface 5.0.0", + "solana-loader-v4-interface 2.2.1", + "solana-message 2.4.0", + "solana-msg 2.2.1", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-secp256k1-recover 2.2.1", + "solana-serde-varint", + "solana-serialize-utils 2.2.1", + "solana-sha256-hasher 2.3.0", + "solana-short-vec", + "solana-slot-hashes 2.2.1", + "solana-slot-history 2.2.1", + "solana-stable-layout 2.2.1", + "solana-stake-interface 1.2.1", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-sysvar-id 2.2.1", + "solana-vote-interface", + "thiserror 2.0.16", + "wasm-bindgen", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-program-entrypoint" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6557cf5b5e91745d1667447438a1baa7823c6086e4ece67f8e6ebfa7a8f72660" +dependencies = [ + "solana-account-info 3.0.0", + "solana-define-syscall 3.0.0", + "solana-msg 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-program-error" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-program-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" +dependencies = [ + "borsh 1.5.7", +] + +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall 2.3.0", +] + +[[package]] +name = "solana-program-memory" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e5660c60749c7bfb30b447542529758e4dbcecd31b1e8af1fdc92e2bdde90a" +dependencies = [ + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-option" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7b4ddb464f274deb4a497712664c3b612e3f5f82471d4e47710fc4ab1c3095" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error 2.2.2", +] + +[[package]] +name = "solana-program-pack" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c169359de21f6034a63ebf96d6b380980307df17a8d371344ff04a883ec4e9d0" +dependencies = [ + "solana-program-error 3.0.0", +] + +[[package]] +name = "solana-program-runtime" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0858a5173268db5c3f81ca3e7f8be60c2b74aeb54527af753ca4459d7b816902" +dependencies = [ + "base64 0.22.1", + "bincode", + "enum-iterator", + "itertools 0.12.1", + "log", + "percentage", + "rand 0.8.5", + "serde", + "solana-account 2.2.1", + "solana-clock 2.2.2", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-fee-structure 2.3.0", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-last-restart-slot 2.2.1", + "solana-log-collector 2.3.6", + "solana-measure 2.3.6", + "solana-program-entrypoint 2.3.0", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sbpf 0.11.1", + "solana-sdk-ids 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-stable-layout 2.2.1", + "solana-svm-callback 2.3.6", + "solana-svm-feature-set 2.3.6", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-sysvar-id 2.2.1", + "solana-timings 2.3.6", + "solana-transaction-context 2.3.6", + "solana-type-overrides 2.3.6", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-program-runtime" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "base64 0.22.1", + "bincode", + "enum-iterator", + "itertools 0.12.1", + "log", + "percentage", + "rand 0.8.5", + "serde", + "solana-account 2.2.1", + "solana-clock 2.2.2", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-fee-structure 2.3.0", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-last-restart-slot 2.2.1", + "solana-log-collector 3.0.0", + "solana-measure 3.0.0", + "solana-metrics", + "solana-program-entrypoint 2.3.0", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sbpf 0.11.1", + "solana-sdk-ids 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-stable-layout 2.2.1", + "solana-svm-callback 3.0.0", + "solana-svm-feature-set 3.0.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-sysvar-id 2.2.1", + "solana-timings 3.0.0", + "solana-transaction-context 3.0.0", + "solana-type-overrides 3.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-program-runtime" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ac66e5a3c07fee403cae74db9377e68faefb71d2b0b7fe4c97d2b97067b6e9e" +dependencies = [ + "base64 0.22.1", + "bincode", + "itertools 0.12.1", + "log", + "percentage", + "rand 0.8.5", + "serde", + "solana-account 3.0.0", + "solana-clock 3.0.0", + "solana-epoch-rewards 3.0.0", + "solana-epoch-schedule 3.0.0", + "solana-fee-structure 3.0.0", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-last-restart-slot 3.0.0", + "solana-program-entrypoint 3.1.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "solana-sbpf 0.12.2", + "solana-sdk-ids 3.0.0", + "solana-slot-hashes 3.0.0", + "solana-stake-interface 2.0.1", + "solana-svm-callback 3.0.3", + "solana-svm-feature-set 3.0.3", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-timings", + "solana-svm-transaction", + "solana-svm-type-overrides", + "solana-system-interface 2.0.0", + "solana-sysvar 3.0.0", + "solana-sysvar-id 3.0.0", + "solana-transaction-context 3.0.3", +] + +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8", + "five8_const", + "getrandom 0.2.16", + "js-sys", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "solana-atomic-u64 2.2.1", + "solana-decode-error", + "solana-define-syscall 2.3.0", + "solana-sanitize 2.2.1", + "solana-sha256-hasher 2.3.0", + "wasm-bindgen", +] + +[[package]] +name = "solana-pubkey" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8909d399deb0851aa524420beeb5646b115fd253ef446e35fe4504c904da3941" +dependencies = [ + "solana-address", +] + +[[package]] +name = "solana-quic-definitions" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf0d4d5b049eb1d0c35f7b18f305a27c8986fc5c0c9b383e97adaa35334379e" +dependencies = [ + "solana-keypair 2.2.3", +] + +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-rent" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b702d8c43711e3c8a9284a4f1bbc6a3de2553deb25b0c8142f9a44ef0ce5ddc1" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-rent-collector" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c1e19f5d5108b0d824244425e43bc78bbb9476e2199e979b0230c9f632d3bf4" +dependencies = [ + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-clock 2.2.2", + "solana-epoch-schedule 2.2.1", + "solana-genesis-config", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-rent-debits" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f6f9113c6003492e74438d1288e30cffa8ccfdc2ef7b49b9e816d8034da18cd" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-reward-info", +] + +[[package]] +name = "solana-reserved-account-keys" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4b22ea19ca2a3f28af7cd047c914abf833486bf7a7c4a10fc652fff09b385b1" +dependencies = [ + "lazy_static", + "solana-feature-set", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-sanitize" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f1bc1357b8188d9c4a3af3fc55276e56987265eb7ad073ae6f8180ee54cecf" + +[[package]] +name = "solana-sanitize" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09694a0fc14e5ffb18f9b7b7c0f15ecb6eac5b5610bf76a1853459d19daf9" + +[[package]] +name = "solana-sbpf" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474a2d95dc819898ded08d24f29642d02189d3e1497bbb442a92a3997b7eb55f" +dependencies = [ + "byteorder", + "combine", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "thiserror 2.0.16", + "winapi", +] + +[[package]] +name = "solana-sbpf" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f224d906c14efc7ed7f42bc5fe9588f3f09db8cabe7f6023adda62a69678e1a" +dependencies = [ + "byteorder", + "combine", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "thiserror 2.0.16", + "winapi", +] + +[[package]] +name = "solana-sdk" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc0e4a7635b902791c44b6581bfb82f3ada32c5bc0929a64f39fe4bb384c86a" +dependencies = [ + "bincode", + "bs58", + "getrandom 0.1.16", + "js-sys", + "serde", + "serde_json", + "solana-account 2.2.1", + "solana-bn254 2.2.2", + "solana-client-traits", + "solana-cluster-type", + "solana-commitment-config", + "solana-compute-budget-interface", + "solana-decode-error", + "solana-derivation-path 2.2.1", + "solana-ed25519-program 2.2.3", + "solana-epoch-info", + "solana-epoch-rewards-hasher", + "solana-feature-set", + "solana-fee-structure 2.3.0", + "solana-genesis-config", + "solana-hard-forks", + "solana-inflation", + "solana-instruction 2.3.0", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-native-token", + "solana-nonce-account", + "solana-offchain-message", + "solana-packet 2.2.1", + "solana-poh-config", + "solana-precompile-error 2.2.2", + "solana-precompiles", + "solana-presigner", + "solana-program", + "solana-program-memory 2.3.1", + "solana-pubkey 2.4.0", + "solana-quic-definitions", + "solana-rent-collector", + "solana-rent-debits", + "solana-reserved-account-keys", + "solana-reward-info", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-secp256k1-program 2.2.3", + "solana-secp256k1-recover 2.2.1", + "solana-secp256r1-program 2.2.4", + "solana-seed-derivable 2.2.1", + "solana-seed-phrase 2.2.1", + "solana-serde", + "solana-serde-varint", + "solana-short-vec", + "solana-shred-version", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "solana-system-transaction", + "solana-time-utils", + "solana-transaction 2.2.3", + "solana-transaction-context 2.3.6", + "solana-transaction-error 2.2.1", + "solana-validator-exit", + "thiserror 2.0.16", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-sdk-ids" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1b6d6aaf60669c592838d382266b173881c65fb1cdec83b37cb8ce7cb89f9ad" +dependencies = [ + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "solana-sdk-macro" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6430000e97083460b71d9fbadc52a2ab2f88f53b3a4c5e58c5ae3640a0e8c00" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "solana-secp256k1-program" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f19833e4bc21558fe9ec61f239553abe7d05224347b57d65c2218aeeb82d6149" +dependencies = [ + "bincode", + "digest 0.10.7", + "libsecp256k1", + "serde", + "serde_derive", + "sha3", + "solana-feature-set", + "solana-instruction 2.3.0", + "solana-precompile-error 2.2.2", + "solana-sdk-ids 2.2.1", + "solana-signature 2.3.0", +] + +[[package]] +name = "solana-secp256k1-program" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8efa767b0188f577edae7080e8bf080e5db9458e2b6ee5beaa73e2e6bb54e99d" +dependencies = [ + "digest 0.10.7", + "k256", + "serde", + "serde_derive", + "sha3", + "solana-signature 3.1.0", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "borsh 1.5.7", + "libsecp256k1", + "solana-define-syscall 2.3.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "394a4470477d66296af5217970a905b1c5569032a7732c367fb69e5666c8607e" +dependencies = [ + "k256", + "solana-define-syscall 3.0.0", + "thiserror 2.0.16", +] + +[[package]] +name = "solana-secp256r1-program" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0ae46da3071a900f02d367d99b2f3058fe2e90c5062ac50c4f20cfedad8f0f" +dependencies = [ + "bytemuck", + "openssl", + "solana-feature-set", + "solana-instruction 2.3.0", + "solana-precompile-error 2.2.2", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-secp256r1-program" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445d8e12592631d76fc4dc57858bae66c9fd7cc838c306c62a472547fc9d0ce6" +dependencies = [ + "bytemuck", + "openssl", + "solana-instruction 3.0.0", + "solana-sdk-ids 3.0.0", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path 2.2.1", +] + +[[package]] +name = "solana-seed-derivable" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff7bdb72758e3bec33ed0e2658a920f1f35dfb9ed576b951d20d63cb61ecd95c" +dependencies = [ + "solana-derivation-path 3.0.0", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-seed-phrase" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc905b200a95f2ea9146e43f2a7181e3aeb55de6bc12afb36462d00a3c7310de" +dependencies = [ + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.9", +] + +[[package]] +name = "solana-serde" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1931484a408af466e14171556a47adaa215953c7f48b24e5f6b0282763818b04" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-serialize-utils" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e41dd8feea239516c623a02f0a81c2367f4b604d7965237fed0751aeec33ed" +dependencies = [ + "solana-instruction-error", + "solana-pubkey 3.0.0", + "solana-sanitize 3.0.1", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall 2.3.0", + "solana-hash 2.3.0", +] + +[[package]] +name = "solana-sha256-hasher" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9b912ba6f71cb202c0c3773ec77bf898fa9fe0c78691a2d6859b3b5b8954719" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall 3.0.0", + "solana-hash 3.0.0", +] + +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-shred-version" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afd3db0461089d1ad1a78d9ba3f15b563899ca2386351d38428faa5350c60a98" +dependencies = [ + "solana-hard-forks", + "solana-hash 2.3.0", + "solana-sha256-hasher 2.3.0", +] + +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "ed25519-dalek 1.0.1", + "five8", + "rand 0.8.5", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-signature" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb8057cc0e9f7b5e89883d49de6f407df655bb6f3a71d0b7baf9986a2218fd9" +dependencies = [ + "ed25519-dalek 2.2.0", + "five8", + "solana-sanitize 3.0.1", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-signature 2.3.0", + "solana-transaction-error 2.2.1", +] + +[[package]] +name = "solana-signer" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bfea97951fee8bae0d6038f39a5efcb6230ecdfe33425ac75196d1a1e3e3235" +dependencies = [ + "solana-pubkey 3.0.0", + "solana-signature 3.1.0", + "solana-transaction-error 3.0.0", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 2.3.0", + "solana-sdk-ids 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-slot-hashes" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a293f952293281443c04f4d96afd9d547721923d596e92b4377ed2360f1746" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-slot-history" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-slot-history" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f914f6b108f5bba14a280b458d023e3621c9973f27f015a4d755b50e88d89e97" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-stable-layout" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1da74507795b6e8fb60b7c7306c0c36e2c315805d16eaaf479452661234685ac" +dependencies = [ + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.7", + "num-traits", + "serde", + "serde_derive", + "solana-clock 2.2.2", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-stake-interface" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f912ae679b683365348dea482dbd9468d22ff258b554fd36e3d3683c2122e3" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-clock 3.0.0", + "solana-cpi 3.0.0", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-system-interface 2.0.0", + "solana-sysvar 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-stake-program" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07857ce48e1d4de2015b32a9bcf2818f44e81a04101ac5c8b1058277f84907af" +dependencies = [ + "agave-feature-set 2.3.6", + "bincode", + "log", + "solana-account 2.2.1", + "solana-bincode 2.2.1", + "solana-clock 2.2.2", + "solana-config-program-client", + "solana-genesis-config", + "solana-instruction 2.3.0", + "solana-log-collector 2.3.6", + "solana-native-token", + "solana-packet 2.2.1", + "solana-program-runtime 2.3.6", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-stake-interface 1.2.1", + "solana-sysvar 2.2.2", + "solana-transaction-context 2.3.6", + "solana-type-overrides 2.3.6", + "solana-vote-interface", +] + +[[package]] +name = "solana-svm-callback" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5498ea1832b503ec4a5c48bfe13994a168ee6515420f435a93ccec62b4820a40" +dependencies = [ + "solana-account 2.2.1", + "solana-precompile-error 2.2.2", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-svm-callback" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "solana-account 2.2.1", + "solana-precompile-error 2.2.2", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-svm-callback" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd48ab6564a0968fc63f3930a3ba6014c98ebb0bd6e182dfa1c1dfe4f67b586" +dependencies = [ + "solana-account 3.0.0", + "solana-clock 3.0.0", + "solana-precompile-error 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-svm-feature-set" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d525b3bb05c5a56c17ec7f4d5b9f838f0bcf006cf423a7c0e1b05ef4e10a2a" + +[[package]] +name = "solana-svm-feature-set" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" + +[[package]] +name = "solana-svm-feature-set" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f90a27275c66047c0ab24af4a5ea7fad1887f58cc6a142b4e60ddd41e46972e" + +[[package]] +name = "solana-svm-log-collector" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c59eacc983f8e66fd7125c9df499cebc6b049c3757b8596a722322fde5def4d" +dependencies = [ + "log", +] + +[[package]] +name = "solana-svm-measure" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444d4584db90598ed2fda524153a7fedba3ff8cbabd59d381be2980643fb26dd" + +[[package]] +name = "solana-svm-timings" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1be04904f1b2926fd42a173432074d3f9becc5bed30c8b7d674421252ca44a1" +dependencies = [ + "eager", + "enum-iterator", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-svm-transaction" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d3945b44e75e7c9f94226c3fdc897199e50b81d333c2675ea389d3d0aa8b605" +dependencies = [ + "solana-hash 3.0.0", + "solana-message 3.0.1", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-signature 3.1.0", + "solana-transaction 3.0.1", +] + +[[package]] +name = "solana-svm-type-overrides" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fdd7f5f6d0d6ffeb9aa4d1a869988d9fc42e2a0377463f1ebcc7eea40cdf054" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "git+https://github.com/rustopian/system.git?branch=create-prefunded-account#176ada90f96bb76d08d1bab02e975d09988b7b24" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "wasm-bindgen", +] + +[[package]] +name = "solana-system-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e1790547bfc3061f1ee68ea9d8dc6c973c02a163697b24263a8e9f2e6d4afa2" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-instruction 3.0.0", + "solana-msg 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-system-program" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "bincode", + "log", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-bincode 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-instruction 2.3.0", + "solana-log-collector 3.0.0", + "solana-nonce", + "solana-nonce-account", + "solana-packet 2.2.1", + "solana-program-runtime 3.0.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-transaction-context 3.0.0", + "solana-type-overrides 3.0.0", +] + +[[package]] +name = "solana-system-transaction" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd98a25e5bcba8b6be8bcbb7b84b24c2a6a8178d7fb0e3077a916855ceba91a" +dependencies = [ + "solana-hash 2.3.0", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-signer 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction 2.2.3", +] + +[[package]] +name = "solana-sysvar" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50c92bc019c590f5e42c61939676e18d14809ed00b2a59695dd5c67ae72c097" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info 2.3.0", + "solana-clock 2.2.2", + "solana-define-syscall 2.3.0", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-instructions-sysvar 2.2.2", + "solana-last-restart-slot 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-slot-history 2.2.1", + "solana-stake-interface 1.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-sysvar" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63205e68d680bcc315337dec311b616ab32fea0a612db3b883ce4de02e0953f9" +dependencies = [ + "base64 0.22.1", + "bincode", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info 3.0.0", + "solana-clock 3.0.0", + "solana-define-syscall 3.0.0", + "solana-epoch-rewards 3.0.0", + "solana-epoch-schedule 3.0.0", + "solana-fee-calculator 3.0.0", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-last-restart-slot 3.0.0", + "solana-program-entrypoint 3.1.0", + "solana-program-error 3.0.0", + "solana-program-memory 3.0.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-sdk-macro 3.0.0", + "solana-slot-hashes 3.0.0", + "solana-slot-history 3.0.0", + "solana-sysvar-id 3.0.0", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-sysvar-id" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5051bc1a16d5d96a96bc33b5b2ec707495c48fe978097bdaba68d3c47987eb32" +dependencies = [ + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", +] + +[[package]] +name = "solana-time-utils" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6af261afb0e8c39252a04d026e3ea9c405342b08c871a2ad8aa5448e068c784c" + +[[package]] +name = "solana-timings" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf5069234bff52d9c541137bc939a0cd5a9707d6536ce34c18580d4b6bf18e91" +dependencies = [ + "eager", + "enum-iterator", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-timings" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "eager", + "enum-iterator", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-bincode 2.2.1", + "solana-feature-set", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-precompiles", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-short-vec", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction-error 2.2.1", + "wasm-bindgen", +] + +[[package]] +name = "solana-transaction" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64928e6af3058dcddd6da6680cbe08324b4e071ad73115738235bbaa9e9f72a5" +dependencies = [ + "solana-address", + "solana-hash 3.0.0", + "solana-instruction 3.0.0", + "solana-instruction-error", + "solana-message 3.0.1", + "solana-sanitize 3.0.1", + "solana-sdk-ids 3.0.0", + "solana-signature 3.1.0", + "solana-transaction-error 3.0.0", +] + +[[package]] +name = "solana-transaction-context" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62899fc8ec399458db3332ec51dfc8379ca8bb5615133510c8b4dca4c5d48111" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-instruction 2.3.0", + "solana-instructions-sysvar 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-transaction-context" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-instruction 2.3.0", + "solana-instructions-sysvar 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", +] + +[[package]] +name = "solana-transaction-context" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239b7583ddb92669855a47e52772e9fa5294d415f6450e55da58e302065e3b39" +dependencies = [ + "bincode", + "qualifier_attr", + "serde", + "serde_derive", + "solana-account 3.0.0", + "solana-instruction 3.0.0", + "solana-instructions-sysvar 3.0.0", + "solana-pubkey 3.0.0", + "solana-rent 3.0.0", + "solana-sbpf 0.12.2", + "solana-sdk-ids 3.0.0", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction 2.3.0", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-transaction-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4222065402340d7e6aec9dc3e54d22992ddcf923d91edcd815443c2bfca3144a" +dependencies = [ + "solana-instruction-error", + "solana-sanitize 3.0.1", +] + +[[package]] +name = "solana-type-overrides" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6a3cca74cf57a3914fb20063ca9422fa4b18f493ed7f34383f1a4b17fc1b55" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "solana-type-overrides" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "solana-validator-exit" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbf6d7a3c0b28dd5335c52c0e9eae49d0ae489a8f324917faf0ded65a812c1d" + +[[package]] +name = "solana-vote-interface" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" +dependencies = [ + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock 2.2.2", + "solana-decode-error", + "solana-hash 2.3.0", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-serde-varint", + "solana-serialize-utils 2.2.1", + "solana-short-vec", + "solana-system-interface 1.0.0", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05857892ac50fe03c125d8445fd790c6768015b76f4ad1e4b4b1499938b357f0" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path 2.2.1", + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-seed-derivable 2.2.1", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "subtle", + "thiserror 2.0.16", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-zk-sdk" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9602bcb1f7af15caef92b91132ec2347e1c51a72ecdbefdaefa3eac4b8711475" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "getrandom 0.2.16", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path 3.0.0", + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", + "solana-signature 3.1.0", + "solana-signer 3.0.0", + "subtle", + "thiserror 2.0.16", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "spl-associated-token-account" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae179d4a26b3c7a20c839898e6aed84cb4477adf108a366c95532f058aea041b" +dependencies = [ + "borsh 1.5.7", + "num-derive", + "num-traits", + "solana-program", + "spl-associated-token-account-client", + "spl-token", + "spl-token-2022", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-associated-token-account-client" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f8349dbcbe575f354f9a533a21f272f3eb3808a49e2fdc1c34393b88ba76cb" +dependencies = [ + "solana-instruction 2.3.0", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "spl-associated-token-account-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6433917b60441d68d99a17e121d9db0ea15a9a69c0e5afa34649cf5ba12612f" +dependencies = [ + "solana-instruction 3.0.0", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error 2.2.2", + "solana-sha256-hasher 2.3.0", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d48cc11459e265d5b501534144266620289720b4c44522a47bc6b63cd295d2f3" +dependencies = [ + "bytemuck", + "solana-program-error 3.0.0", + "solana-sha256-hasher 3.0.0", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.104", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.104", + "thiserror 1.0.69", +] + +[[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 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-zk-sdk 2.3.6", + "spl-pod 0.5.1", + "spl-token-confidential-transfer-proof-extraction 0.3.0", +] + +[[package]] +name = "spl-memo" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info 2.3.0", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "spl-pod" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-program-option 2.2.1", + "solana-pubkey 2.4.0", + "solana-zk-sdk 2.3.6", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-pod" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1233fdecd7461611d69bb87bc2e95af742df47291975d21232a0be8217da9de" +dependencies = [ + "borsh 1.5.7", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "num_enum", + "solana-program-error 3.0.0", + "solana-program-option 3.0.0", + "solana-pubkey 3.0.0", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.16", +] + +[[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 2.2.1", + "solana-program-error 2.2.2", + "spl-program-error-derive", + "thiserror 2.0.16", +] + +[[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.104", +] + +[[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 2.3.0", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-type-length-value 0.8.0", + "thiserror 2.0.16", +] + +[[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 2.3.0", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sysvar 2.2.2", + "thiserror 2.0.16", +] + +[[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 2.3.0", + "solana-clock 2.2.2", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-native-token", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-security-txt", + "solana-system-interface 1.0.0", + "solana-sysvar 2.2.2", + "solana-zk-sdk 2.3.6", + "spl-elgamal-registry", + "spl-memo", + "spl-pod 0.5.1", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction 0.3.0", + "spl-token-confidential-transfer-proof-generation 0.4.0", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "spl-transfer-hook-interface", + "spl-type-length-value 0.8.0", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-2022-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0888304af6b3d839e435712e6c84025e09513017425ff62045b6b8c41feb77d9" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info 3.0.0", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-program-option 3.0.0", + "solana-program-pack 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.1", + "spl-token-confidential-transfer-proof-extraction 0.5.0", + "spl-token-confidential-transfer-proof-generation 0.5.0", + "spl-token-group-interface 0.7.1", + "spl-token-metadata-interface 0.8.0", + "spl-type-length-value 0.9.0", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ab20faf7b5edaa79acd240e0f21d5a2ef936aa99ed98f698573a2825b299c4" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519 2.3.6", + "solana-zk-sdk 2.3.6", +] + +[[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 2.3.0", + "solana-curve25519 2.3.6", + "solana-instruction 2.3.0", + "solana-instructions-sysvar 2.2.2", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-zk-sdk 2.3.6", + "spl-pod 0.5.1", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a22217af69b7a61ca813f47c018afb0b00b02a74a4c70ff099cd4287740bc3d" +dependencies = [ + "bytemuck", + "solana-account-info 3.0.0", + "solana-curve25519 2.3.6", + "solana-instruction 3.0.0", + "solana-instructions-sysvar 3.0.0", + "solana-msg 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.1", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae5b124840d4aed474cef101d946a798b806b46a509ee4df91021e1ab1cef3ef" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 2.3.6", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a2b41095945dc15274b924b21ccae9b3ec9dc2fdd43dbc08de8c33bbcd915" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.16", +] + +[[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 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "452d0f758af20caaa10d9a6f7608232e000d4c74462f248540b3d2ddfa419776" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "spl-discriminator 0.5.1", + "spl-pod 0.7.1", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-interface" +version = "0.0.0" +source = "git+https://github.com/solana-program/token.git#50ad3b0797811ad9e9d330e886cfff400f7a3b4c" +dependencies = [ + "pinocchio", + "pinocchio-pubkey", +] + +[[package]] +name = "spl-token-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c564ac05a7c8d8b12e988a37d82695b5ba4db376d07ea98bc4882c81f96c7f3" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-program-option 3.0.0", + "solana-program-pack 3.0.0", + "solana-pubkey 3.0.0", + "solana-sdk-ids 3.0.0", + "thiserror 2.0.16", +] + +[[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.5.7", + "num-derive", + "num-traits", + "solana-borsh 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-type-length-value 0.8.0", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c467c7c3bd056f8fe60119e7ec34ddd6f23052c2fa8f1f51999098063b72676" +dependencies = [ + "borsh 1.5.7", + "num-derive", + "num-traits", + "solana-borsh 3.0.0", + "solana-instruction 3.0.0", + "solana-program-error 3.0.0", + "solana-pubkey 3.0.0", + "spl-discriminator 0.5.1", + "spl-pod 0.7.1", + "spl-type-length-value 0.9.0", + "thiserror 2.0.16", +] + +[[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 2.3.0", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value 0.8.0", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-type-length-value" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 2.0.16", +] + +[[package]] +name = "spl-type-length-value" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca20a1a19f4507a98ca4b28ff5ed54cac9b9d34ed27863e2bde50a3238f9a6ac" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info 3.0.0", + "solana-msg 3.0.0", + "solana-program-error 3.0.0", + "spl-discriminator 0.5.1", + "spl-pod 0.7.1", + "thiserror 2.0.16", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +dependencies = [ + "thiserror-impl 2.0.16", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2 0.6.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", +] + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[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 = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +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", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[patch.unused]] +name = "indicatif" +version = "0.18.0" +source = "git+https://github.com/mitsuhiko/indicatif?tag=0.18.0#354b7325467252009f8bc0bd7155798a17deb84a" + +[[patch.unused]] +name = "mollusk-svm-bencher" +version = "0.4.1" +source = "git+https://github.com/rustopian/mollusk.git?branch=rustopian%2Fcreate-prefunded-account#257dbfc3b2132112f02c23458167cdc9aa5f9c3d" + +[[patch.unused]] +name = "solana-builtins" +version = "3.0.0" +source = "git+https://github.com/rustopian/agave.git?branch=create-prefunded-account#684712c3283870b8571a8984557ac8c944fbf697" diff --git a/p-ata/Cargo.toml b/p-ata/Cargo.toml new file mode 100644 index 00000000..e01360a8 --- /dev/null +++ b/p-ata/Cargo.toml @@ -0,0 +1,58 @@ +[workspace] + +[package] +name = "pinocchio-ata-program" +version = "0.1.0" +description = "A pinocchio-based Associated Token Account (aka 'p-ata') program" +readme = "./README.md" +autobenches = false +edition = "2021" +build = "build.rs" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["create-prefunded-account"] +create-prefunded-account = [] +build-programs = [] +std = [] + +[build-dependencies] +serde_json = "1.0" +solana-pubkey = "2.2.1" + +[patch.crates-io] +pinocchio = { version = "0.9.2", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account", default-features = false } +pinocchio-pubkey = { version = "0.3.0", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account" } +pinocchio-system = { version = "0.3.0", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account" } +indicatif = { git = "https://github.com/mitsuhiko/indicatif", tag = "0.18.0" } +solana-system-program = { version = "3.0", git = "https://github.com/rustopian/agave.git", branch = "create-prefunded-account" } +solana-builtins = { version = "3.0", git = "https://github.com/rustopian/agave.git", branch = "create-account-allow-prefund" } +solana-system-interface = { version = "1.0.0", git = "https://github.com/rustopian/system.git", branch = "create-prefunded-account" } +mollusk-svm = { version = "0.4.1", git = "https://github.com/rustopian/mollusk.git", branch = "rustopian/create-prefunded-account" } +mollusk-svm-bencher = { version = "0.4.1", git = "https://github.com/rustopian/mollusk.git", branch = "rustopian/create-prefunded-account" } + +[dependencies] +# Non-optional dependencies +pinocchio = { version = "0.9.2", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account", default-features = false } +pinocchio-log = { version = "0.4", features = ["macro"] } +pinocchio-pubkey = { version = "0.3.0", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account" } +pinocchio-system = { version = "0.3.0", git = "https://github.com/rustopian/pinocchio.git", branch = "create-prefunded-account" } +spl-token-interface = { version = "^0", git = "https://github.com/solana-program/token.git" } + +[dev-dependencies] +curve25519-dalek = { version = "4.1.3", default-features = false } +mollusk-svm = { version = "0.6.1", git = "https://github.com/rustopian/mollusk.git", branch = "rustopian/create-prefunded-account", features = ["all-builtins"] } +solana-keypair = "2.2.3" +solana-program = "2.3.0" +solana-pubkey = { version = "2.2.1", features = ["curve25519"] } +solana-sdk = "2.3.1" +solana-sdk-ids = "2.2.1" +solana-signer = "2.2.1" +spl-associated-token-account = "7.0.0" +spl-token = { version = "8.0.0", features = ["no-entrypoint"] } +spl-token-2022 = { version = "8.0.1", features = ["no-entrypoint"] } +spl-token-group-interface = "0.6.0" +spl-token-metadata-interface = "0.7.0" +ata-mollusk-harness = { version = "1.0.0", path = "../test-harness" } \ No newline at end of file diff --git a/p-ata/README.md b/p-ata/README.md new file mode 100644 index 00000000..1e09447d --- /dev/null +++ b/p-ata/README.md @@ -0,0 +1,207 @@ +# `p-ata` + +A `pinocchio`-based Associated Token Account program. + +## Overview + +p-ata (pinocchio-ata) is a drop-in replacement for SPL ATA. Following in the footsteps of [p-token](https://github.com/solana-program/token/tree/main/p-token), it uses pinocchio instead of solana-program to reduce compute usage. Plus, it includes a number of additional improvements. + +- `no_std` crate +- Fully compatible with instruction and account layout of SPL Associated Token Account +- Minimized CU usage + +## New Features (not available in SPL ATA) +- `RecoverNested` works with multisig accounts (satisfying #24) +- `CreatePrefundedAccount` is supported for cheaper calls of p-ata's `Create` when the account rent has been topped up in advance. Conditional on [SIMD-312](https://github.com/solana-foundation/solana-improvement-documents/pull/312), but alternative code is provided if `not(feature = "create-prefunded-account")`. Enabling this feature saves this flow ~2500 CUs (Compute Units). Currently this PR patches in branches with `CreatePrefundedAccount` support in `agave`, `system`, `pinocchio`, and `mollusk`. +- In descending order of significance,`bump`, `rent`, and `token_account_len` can be passed in by client to save compute. + +## Notable Performance Improvements +- No strings attached, of course. Developed using [pinocchio](https://github.com/anza-xyz/pinocchio). +- SPL ATA always calls `InitializeImmutableOwner` via CPI. `InitializeImmutableOwner` is a no-op in Token, though not in Token 2022. In p-ata, if the relevant program is Token (not 2022), all `ImmutableOwner` logic is skipped. +- In p-ata, SPL Token ATA data length is assumed to be `TokenAccount::LEN`. For Token-2022, this program avoids CPI calls by using its own `calculate_account_size_from_mint_extensions`. For any other token program, ATA data length is checked via CPI. Of course, token length may be passed in as `token_account_len` to save compute. +- A few assertions are removed to save compute, when ignoring them fails later in the ATA transaction anyway. This results in different errors in a few cases (see below). + +## Test Suites +General test capabilities included are: +1. `/src/tests/utils/mollusk_adapter.rs` - The original SPL ATA suite is run with a Mollusk adapter, allowing the unmodified solana_program_test files for SPL ATA to be run on p-ata. +2. `/src/tests/migrated` - (Redundancy) A migrated version of the same tests, written to run on Mollusk. +3. `/src/tests` - Unit tests for the various helper functions in processor.rs. +4. `/src/tests/token_account_len` - Tests for token account data length logic, whether passed in or calculated in-program. Includes exhaustive tests for the `calculate_account_size_from_mint_extensions` function, testing the results of this function for all possible combinations of token extensions against the results from Token-2022's `GetAccountDataSize` logic. +5. `/src/tests/bump` - Mollusk tests ensuring the safety of various scenarios where `bump` is passed in. + +The branch `p-ata-bencher` adds these: +6. `/src/tests/benches` - A benchmark suite, which benches categories of operations in p-ata against SPL ATA and verifies that accounts are changed in the same way, byte-for-byte. See "Benchmarking" below. +7. `/src/tests/benches/failure_scenarios.rs` - 26 failure tests which compare errors yielded by p-ata against those by SPL ATA. All scenarios must ensure that baseline succeeds before mutating inputs to failure state. + +Items 1 to 5 are run on `cargo test` + +``` +cargo build --features build-programs && cargo test +``` + +Items 6 and 7 are run on `cargo bench --features std`, in branch `p-ata-bencher`: + +## Benchmarking +Set `BENCH_ITERATIONS` to average a number of runs. If only 1 iteration is used, optimal bump wallets will be found instead of random wallets each run. + +``` +BENCH_ITERATIONS=1 cargo bench --features std +``` + +### "Best run" numbers (ideal bumps) *as of 2025-08-11, ecde2ca* + +| Test | SPL ATA | p-ata | bump arg | all optimizations | notes | +|-----------------------|--------:|------:|---------:|------------------:|-----------------:| +| create_idempotent | 3669 | 1732 | 590 | 590 | | +| create | 12364 | 4842 | 3323 | 3216 | | +| create_token2022 | 14692 | 7642 | 6123 | 5987 | | +| create_topup | 15817 | 4710 | 3191 | 3083 | `CreateAccountPrefunded` | +| create_topup_nocap | 15817 | 7476 | 5959 | 5851 | no `CreateAccountPrefunded` | +| create_extended | 17620 | 9771 | 8251 | 7997 | | +| recover_nested | 12851 | 8100 | N/A | 8100 | rare instruction | +| recover_multisig | N/A | 8412 | N/A | 8412 | rare instruction | +| worst_case_create | 19864 | 15187 | 3323 | 3216 | hard-to-find bump | + +### Average of 10,000 random wallets *as of 2025-08-11, ecde2cad* + +| Test | SPL ATA | p-ata | bump arg | all optimizations | notes | +|-----------------------|--------:|------:|---------:|------------------:|-----------------:| +| create_idempotent | 4914 | 3234 | 948 | 948 | | +| create | 14194 | 6343 | 3692 | 3589 | | +| create_token2022 | 16057 | 9140 | 6491 | 6362 | | +| create_topup | 17317 | 6183 | 3561 | 3449 | `CreateAccountPrefunded` | +| create_topup_no_cap | 17287 | 8987 | 6324 | 6209 | no `CreateAccountPrefunded` | +| create_extended | 19420 | 11289 | 8618 | 8366 | | +| recover_nested | 17066 | 12576 | N/A | 12576 | rare instruction | +| recover_multisig | N/A | 12875 | N/A | 12875 | rare instruction | + +All benchmarks also check for byte-for-byte equivalence with SPL ATA. + +"optimum args" are: +- no special optimizations for `recover` tests +- for all `create` tests, `bump` +- for Token-2022, `token_account_len` passed in (after `bump`) +- for `create` tests other than `create_idemp`, `rent` passed in as an optional additional account + +To benchmark (and run a set of failure tests and byte-for-byte equivalence tests) from the /p-ata directory on branch `p-ata-bencher`: + +``` +cargo build --features build-programs && cargo bench --features std +``` + +Mollusk's extensive debug logs are filtered out *unless* a test has an unexpected result. To show all of them, run `cargo bench --features std,full-debug-logs`. + +## Tests with byte-for-byte checking on changed accounts +(byte-for-byte is irrelevant for "P-ATA optimization working" tests) +``` +--- Testing variant create_idempotent --- +--- Testing create_idempotent_ --- ✅ Byte-for-Byte Identical +--- Testing create_idempotent__rent --- ✅ Byte-for-Byte Identical +--- Testing create_idempotent__bump --- 🚀 P-ATA optimization working +--- Testing create_idempotent__rent_bump --- 🚀 P-ATA optimization working + +--- Testing variant create --- +--- Testing create_ --- ✅ Byte-for-Byte Identical +--- Testing create__rent --- ✅ Byte-for-Byte Identical +--- Testing create__bump --- 🚀 P-ATA optimization working +--- Testing create__rent_bump --- 🚀 P-ATA optimization working + +--- Testing variant create_topup --- +Using P-ATA prefunded binary for create_topup +--- Testing create_topup_ --- ✅ Byte-for-Byte Identical +--- Testing create_topup__rent --- ✅ Byte-for-Byte Identical +--- Testing create_topup__bump --- 🚀 P-ATA optimization working +--- Testing create_topup__rent_bump --- 🚀 P-ATA optimization working + +--- Testing variant create_topup_no_cap --- +--- Testing create_topup_no_cap_ --- ✅ Byte-for-Byte Identical +--- Testing create_topup_no_cap__rent --- ✅ Byte-for-Byte Identical +--- Testing create_topup_no_cap__bump --- 🚀 P-ATA optimization working +--- Testing create_topup_no_cap__rent_bump --- 🚀 P-ATA optimization working + +--- Testing variant create_token2022 --- +--- Testing create_token2022_ --- ✅ Byte-for-Byte Identical +--- Testing create_token2022__rent --- ✅ Byte-for-Byte Identical +--- Testing create_token2022__bump --- 🚀 P-ATA optimization working +--- Testing create_token2022__rent_bump --- 🚀 P-ATA optimization working +--- Testing create_token2022__bump_token_account_len --- 🚀 P-ATA optimization working +--- Testing create_token2022__rent_bump_token_account_len --- 🚀 P-ATA optimization working + +--- Testing variant recover_nested --- +--- Testing recover_nested_ --- ✅ Byte-for-Byte Identical + +--- Testing variant recover_multisig --- +--- Testing recover_multisig_ --- 🚀 P-ATA optimization working +``` + +### Should-Fail Test Results +``` +--- Basic Account Ownership Failure Tests --- +Test: fail_wrong_payer_owner + ✅ Both failed (expected) +Test: fail_payer_not_signed + ✅ Both failed (expected) +Test: fail_wrong_system_program + ✅ Both failed (expected) +Test: fail_wrong_token_program + ⚠️ Different error messages (both failed) +Test: fail_insufficient_funds + ✅ Both failed (expected) + +--- Address Derivation and Structure Failure Tests --- +Test: fail_wrong_ata_address + ⚠️ Different error messages (both failed) +Test: fail_mint_wrong_owner + ✅ Both failed (expected) +Test: fail_invalid_mint_structure + ✅ Both failed (expected) +Test: fail_invalid_token_account_structure + ✅ Both failed (expected) +Test: fail_invalid_discriminator + ✅ Both failed (expected) +Test: fail_invalid_bump_value + ✅ Failed as expected (P-ATA-only feature) + +--- Recovery Operation Failure Tests --- +Test: fail_recover_wallet_not_signer + ✅ Both failed (expected) +Test: fail_recover_multisig_insufficient_signers + ✅ Both failed (expected) +Test: fail_recover_wrong_nested_ata_address + ⚠️ Different error messages (both failed) +Test: fail_recover_wrong_destination_address + ⚠️ Different error messages (both failed) +Test: fail_recover_invalid_bump_value + ✅ Failed as expected (P-ATA-only feature) + +--- Additional Validation Coverage Tests --- +Test: fail_ata_owned_by_system_program + ✅ Both failed (expected) +Test: fail_wrong_token_account_size + ✅ Both failed (expected) +Test: fail_token_account_wrong_mint + ✅ Both failed (expected) +Test: fail_token_account_wrong_owner + ⚠️ Different error messages (both failed) +Test: fail_immutable_account + ✅ Both failed (expected) +Test: fail_create_extended_mint_v1 + ✅ Both failed (expected) + +⚠️ "Different Error" Details: + fail_wrong_token_program - Different Error Messages: + P-ATA: UnknownError(PrivilegeEscalation) + SPL ATA: Failure(InvalidSeeds) + fail_wrong_ata_address - Different Error Messages: + P-ATA: UnknownError(PrivilegeEscalation) + SPL ATA: Failure(InvalidSeeds) + fail_recover_wrong_nested_ata_address - Different Error Messages: + P-ATA: UnknownError(PrivilegeEscalation) + SPL ATA: Failure(InvalidSeeds) + fail_recover_wrong_destination_address - Different Error Messages: + P-ATA: UnknownError(PrivilegeEscalation) + SPL ATA: Failure(InvalidSeeds) + fail_token_account_wrong_owner - Different Error Messages: + P-ATA: Failure(IllegalOwner) + SPL ATA: Failure(Custom(0)) +``` diff --git a/p-ata/build.rs b/p-ata/build.rs new file mode 100644 index 00000000..ace9d259 --- /dev/null +++ b/p-ata/build.rs @@ -0,0 +1,242 @@ +//! This build script is used to generate `generated_tests.rs` use the SPL ATA +//! tests and the mollusk adapter in src/tests/utils/mollusk_adapter.rs. +//! +//! If feature `build-programs` is enabled, it also updates submodules and builds +//! module and submodule programs. + +#[cfg(feature = "build-programs")] +use std::{fs, path::Path, process::Command}; + +#[cfg(feature = "build-programs")] +use solana_pubkey::Pubkey; + +fn main() { + println!("cargo:rerun-if-changed=programs/token"); + println!("cargo:rerun-if-changed=programs/token-2022"); + + #[cfg(feature = "build-programs")] + builder::build_programs(); +} + +#[cfg(feature = "build-programs")] +mod builder { + use super::*; + + pub fn build_programs() { + println!("cargo:warning=Building token programs for benchmarking..."); + + let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + + update_submodules(&manifest_dir); + build_p_token(&manifest_dir, Path::new("")); + build_token_2022(&manifest_dir, Path::new("")); + build_spl_ata(&manifest_dir, Path::new("")); + build_p_ata_variants(&manifest_dir); + + println!("cargo:warning=Token programs built successfully!"); + } + + fn update_submodules(manifest_dir: &str) { + println!("cargo:warning=Updating git submodules..."); + + let output = Command::new("git") + .args(["submodule", "update", "--init", "--recursive"]) + .current_dir(manifest_dir) + .output() + .expect("Failed to execute git submodule update"); + + if !output.status.success() { + panic!( + "Git submodule update failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + } + + fn build_p_token(manifest_dir: &str, _programs_dir: &Path) { + println!("cargo:warning=Building p-token program..."); + + let p_token_dir = Path::new(manifest_dir).join("programs/token/p-token"); + let output = Command::new("cargo") + .args(["build-sbf"]) + .current_dir(&p_token_dir) + .output() + .expect("Failed to execute cargo build-sbf for p-token"); + + if !output.status.success() { + panic!( + "p-token build failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + println!("cargo:warning=P-token built successfully to programs/token/target/deploy/"); + } + + fn build_token_2022(manifest_dir: &str, _programs_dir: &Path) { + println!("cargo:warning=Building token-2022 program..."); + + let token_2022_dir = Path::new(manifest_dir).join("programs/token-2022/program"); + + let output = Command::new("cargo") + .args(["build-sbf"]) + .current_dir(&token_2022_dir) + .output() + .expect("Failed to execute cargo build-sbf for token-2022"); + + if !output.status.success() { + panic!( + "token-2022 build failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + println!( + "cargo:warning=Token-2022 built successfully to programs/token-2022/target/deploy/" + ); + } + + fn build_spl_ata(manifest_dir: &str, _programs_dir: &Path) { + println!("cargo:warning=Building SPL ATA program..."); + + let spl_ata_dir = Path::new(manifest_dir) + .parent() + .expect("Failed to get parent directory") + .join("program"); + + if !spl_ata_dir.exists() { + println!( + "cargo:warning=SPL ATA program directory not found at {:?}, skipping...", + spl_ata_dir + ); + return; + } + + let output = Command::new("cargo") + .args(["build-sbf"]) + .current_dir(&spl_ata_dir) + .output() + .expect("Failed to execute cargo build-sbf for SPL ATA"); + + if !output.status.success() { + panic!( + "SPL ATA build failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + println!("cargo:warning=SPL ATA built successfully to ../target/deploy/"); + } + + fn build_p_ata_variants(manifest_dir: &str) { + println!("cargo:warning=Building P-ATA variants..."); + + build_p_ata_prefunded(manifest_dir); + build_p_ata_legacy(manifest_dir); + } + + fn build_p_ata_prefunded(manifest_dir: &str) { + println!("cargo:warning=Building P-ATA prefunded variant..."); + + let output = Command::new("cargo") + .args([ + "build-sbf", + "--features", + "create-prefunded-account", + "--no-default-features", + ]) + .current_dir(manifest_dir) + .output() + .expect("Failed to execute cargo build-sbf for P-ATA prefunded"); + + if !output.status.success() { + panic!( + "P-ATA prefunded build failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + // Read and print the program ID for debugging + let deploy_dir = Path::new(manifest_dir).join("target/deploy"); + let keypair_path = deploy_dir.join("pinocchio_ata_program-keypair.json"); + + if let Ok(keypair_data) = std::fs::read_to_string(&keypair_path) { + if let Ok(keypair_bytes) = serde_json::from_str::>(&keypair_data) { + if keypair_bytes.len() >= 64 { + let pubkey_bytes: [u8; 32] = keypair_bytes[32..64].try_into().unwrap(); + let program_id = Pubkey::from(pubkey_bytes); + println!( + "cargo:warning=Built P-ATA prefunded with program ID: {}", + program_id + ); + } + } + } + + // Rename the results to prefunded names + let default_so = deploy_dir.join("pinocchio_ata_program.so"); + let default_keypair = deploy_dir.join("pinocchio_ata_program-keypair.json"); + let prefunded_so = deploy_dir.join("pinocchio_ata_program_prefunded.so"); + let prefunded_keypair = deploy_dir.join("pinocchio_ata_program_prefunded-keypair.json"); + + if let Err(e) = fs::rename(&default_so, &prefunded_so) { + panic!("Failed to rename prefunded .so file: {}", e); + } + if let Err(e) = fs::rename(&default_keypair, &prefunded_keypair) { + panic!("Failed to rename prefunded keypair file: {}", e); + } + + // Read and print the prefunded program ID for debugging + if let Ok(keypair_content) = fs::read_to_string(&prefunded_keypair) { + if let Ok(keypair_json) = serde_json::from_str::>(&keypair_content) { + if keypair_json.len() >= 64 { + let pubkey_bytes = &keypair_json[32..64]; + let pubkey = Pubkey::new_from_array(pubkey_bytes.try_into().unwrap()); + println!( + "cargo:warning=Built P-ATA prefunded with program ID: {}", + pubkey + ); + } + } + } + + println!("cargo:warning=P-ATA prefunded built and renamed successfully"); + } + + fn build_p_ata_legacy(manifest_dir: &str) { + println!("cargo:warning=Building P-ATA legacy variant..."); + + let output = Command::new("cargo") + .args(["build-sbf", "--no-default-features"]) + .current_dir(manifest_dir) + .output() + .expect("Failed to execute cargo build-sbf for P-ATA legacy"); + + if !output.status.success() { + panic!( + "P-ATA legacy build failed: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + + let deploy_dir = Path::new(manifest_dir).join("target/deploy"); + let keypair_path = deploy_dir.join("pinocchio_ata_program-keypair.json"); + + if keypair_path.exists() { + if let Ok(keypair_content) = fs::read_to_string(&keypair_path) { + if let Ok(keypair_json) = serde_json::from_str::>(&keypair_content) { + if keypair_json.len() >= 64 { + let pubkey_bytes = &keypair_json[32..64]; + let pubkey = Pubkey::new_from_array(pubkey_bytes.try_into().unwrap()); + println!( + "cargo:warning=Built P-ATA legacy with program ID: {}", + pubkey + ); + } + } + } + } + + println!("cargo:warning=P-ATA legacy built successfully to target/deploy/"); + } +} diff --git a/p-ata/rust-toolchain.toml b/p-ata/rust-toolchain.toml new file mode 100644 index 00000000..fcb78ec5 --- /dev/null +++ b/p-ata/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.84.1" diff --git a/p-ata/src/account.rs b/p-ata/src/account.rs new file mode 100644 index 00000000..a5179852 --- /dev/null +++ b/p-ata/src/account.rs @@ -0,0 +1,101 @@ +//! Core account creation utilities for Program Derived Addresses (PDAs). +//! +//! This is the only code that uses the `CreatePrefundedAccount` instruction. +use { + pinocchio::{ + account_info::AccountInfo, + instruction::{Seed, Signer}, + pubkey::Pubkey, + sysvars::rent::Rent, + ProgramResult, + }, + pinocchio_system::instructions::CreateAccount, +}; + +#[cfg(feature = "create-prefunded-account")] +use pinocchio_system::instructions::CreatePrefundedAccount; + +#[cfg(not(feature = "create-prefunded-account"))] +use pinocchio_system::instructions::{Allocate, Assign, Transfer}; + +/// Create a Program Derived Address (PDA) account. +/// +/// ## Arguments +/// +/// * `payer` - Account to deduct SOL from (must be signer and writable) +/// * `rent` - Rent sysvar reference for minimum balance calculation +/// * `space` - Size of the account data field in bytes +/// * `target_program_owner` - Program that will own the new account +/// * `pda` - Pre-derived PDA address (account to create) +/// * `pda_signer_seeds` - Exactly 4 seeds [wallet, token_program, mint, bump] +/// +/// ## Behavior +/// +/// - **Account has 0 lamports**: Uses `CreateAccount` instruction +/// - **Account has >0 lamports**: Uses `CreatePrefundedAccount` instruction +/// - **Account has >0 lamports (legacy)**: Uses `Transfer` + `Allocate` + `Assign` sequence +/// +/// `pda_signer_seeds` must correctly derive `pda`, and `pda` must be empty +/// and owned by the system program, or the system program instructions called +/// by this function will fail. +#[inline(always)] +pub(crate) fn create_pda_account( + payer: &AccountInfo, + rent: &Rent, + space: usize, + target_program_owner: &Pubkey, + pda: &AccountInfo, + pda_signer_seeds: &[Seed; 4], +) -> ProgramResult { + let current_lamports = pda.lamports(); + + let signer = Signer::from(pda_signer_seeds); + + let required_lamports = rent.minimum_balance(space); + + if current_lamports > 0 { + #[cfg(feature = "create-prefunded-account")] + { + CreatePrefundedAccount { + from: payer, + to: pda, + lamports: required_lamports.saturating_sub(current_lamports), + space: space as u64, + owner: target_program_owner, + } + .invoke_signed(&[signer]) + } + #[cfg(not(feature = "create-prefunded-account"))] + { + if required_lamports > current_lamports { + Transfer { + from: payer, + to: pda, + lamports: required_lamports - current_lamports, + } + .invoke()?; + } + + Allocate { + account: pda, + space: space as u64, + } + .invoke_signed(&[signer.clone()])?; + + Assign { + account: pda, + owner: target_program_owner, + } + .invoke_signed(&[signer]) + } + } else { + CreateAccount { + from: payer, + to: pda, + lamports: required_lamports, + space: space as u64, + owner: target_program_owner, + } + .invoke_signed(&[signer]) + } +} diff --git a/p-ata/src/entrypoint.rs b/p-ata/src/entrypoint.rs new file mode 100644 index 00000000..55f1fecf --- /dev/null +++ b/p-ata/src/entrypoint.rs @@ -0,0 +1,140 @@ +#![allow(unexpected_cfgs)] + +use { + crate::{ + processor::{ + check_idempotent_account, parse_create_accounts, + process_create_associated_token_account, + }, + recover::process_recover_nested, + }, + pinocchio::{ + account_info::AccountInfo, no_allocator, nostd_panic_handler, program_entrypoint, + program_error::ProgramError, pubkey::Pubkey, ProgramResult, + }, +}; + +/// Maximum allowed account `known_account_data_length` to prevent creation +/// of accounts that are expensive to work with. This mitigates potential +/// attacks where callers could create very large, expensive-to-work-with +/// accounts for others. +/// +/// Any token program requiring a larger length must rely on CPI calls to +/// determine the account length and cannot pass in `known_account_data_length`. +pub const MAX_SANE_ACCOUNT_LENGTH: u16 = 1024; + +program_entrypoint!(process_instruction); +no_allocator!(); +nostd_panic_handler!(); + +/// Main instruction processor for the p-ATA program. +/// +/// ## Instruction Format +/// +/// ### Create ATA (Non-Idempotent) - Discriminator: 0 or Empty +/// ```ignore +/// [0] or [] -> compute bump and ATA account data length on-chain +/// [0, bump] -> use provided bump, compute ATA account data length +/// [0, bump, len_low, len_high] -> use provided bump and ATA account data length +/// ``` +/// +/// ### Create ATA (Idempotent) - Discriminator: 1 +/// ```ignore +/// [1] -> compute bump and ATA account data length on-chain +/// [1, bump] -> use provided bump, compute ATA account data length +/// [1, bump, len_low, len_high] -> use provided bump and ATA account data length +/// ``` +/// +/// ### Recover Nested ATA - Discriminator: 2 +/// ```ignore +/// [2] -> computes all bumps on-chain +/// ``` +/// +/// ## Account Layout (Create) +/// ```ignore +/// [0] payer (signer, writable) - pays for account creation (and rent if applicable) +/// [1] associated_token_account (writable) - account to create +/// [2] wallet (signer) - token account owner +/// [3] mint - token mint account +/// [4] system_program - system program +/// [5] token_program - token program +/// [6] rent_sysvar (optional) - rent sysvar (for optimization) +/// ``` +/// +/// ## Security +/// +/// - All bump hints are validated for canonicality +/// - `token_account_len` is bounded by `MAX_SANE_ACCOUNT_LENGTH` +#[inline(always)] +pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + data: &[u8], +) -> ProgramResult { + match data { + // Empty data defaults to Create (discriminator 0) - preserving backward compatibility + [] => { + let create_accounts = parse_create_accounts(accounts)?; + process_create_associated_token_account(program_id, &create_accounts, None, None) + } + [discriminator, instruction_data @ ..] => { + let idempotent = match *discriminator { + 0 => false, + 1 => true, + 2 => { + return match instruction_data { + [] => process_recover_nested(program_id, accounts), + _ => Err(pinocchio::program_error::ProgramError::InvalidInstructionData), + } + } + _ => return Err(pinocchio::program_error::ProgramError::InvalidInstructionData), + }; + + let create_accounts = parse_create_accounts(accounts)?; + let (expected_bump, known_account_len): (Option, Option) = + match instruction_data { + // No additional data - compute bump and account_len on-chain (old SPL ATA behavior) + [] => (None, None), + // Only bump provided + [bump] => (Some(*bump), None), + // Bump + account_len provided + [expected_bump, account_len_bytes @ ..] => { + let account_len = u16::from_le_bytes( + account_len_bytes + .try_into() + .map_err(|_| ProgramError::InvalidInstructionData)?, + ); + + if account_len > MAX_SANE_ACCOUNT_LENGTH { + return Err(ProgramError::InvalidInstructionData); + } + + (Some(*expected_bump), Some(account_len as usize)) + } + }; + + // SAFETY: no mutable borrows of any accounts have occurred. + if idempotent + && unsafe { + check_idempotent_account( + create_accounts.associated_token_account_to_create, + create_accounts.wallet, + create_accounts.mint, + create_accounts.token_program, + program_id, + expected_bump, + )? + } + { + return Ok(()); + } + + process_create_associated_token_account( + program_id, + &create_accounts, + expected_bump, + known_account_len, + ) + } + } +} diff --git a/p-ata/src/lib.rs b/p-ata/src/lib.rs new file mode 100644 index 00000000..2c0da68b --- /dev/null +++ b/p-ata/src/lib.rs @@ -0,0 +1,17 @@ +//! # p-ATA: pinocchio Associated Token Account Program +//! +//! An optimized implementation of the Associated Token Account (ATA) program + +#![no_std] + +pub mod account; +pub mod entrypoint; +pub mod processor; +pub mod recover; +pub mod size; + +// Compile-time check to ensure tests/benches use --features std +#[cfg(all(test, not(feature = "std")))] +compile_error!("Tests require the 'std' feature. Use: cargo test --features std"); +#[cfg(any(test, feature = "std"))] +extern crate std; diff --git a/p-ata/src/processor.rs b/p-ata/src/processor.rs new file mode 100644 index 00000000..9ccea829 --- /dev/null +++ b/p-ata/src/processor.rs @@ -0,0 +1,974 @@ +//! Core ATA creation and validation logic. +//! +//! This module handles the main Associated Token Account creation flow, including: +//! - Account parsing and validation +//! - Idempotent operation support +//! - Bump seed validation and canonicalization +//! - Account initialization for both Token and Token-2022 programs +//! - Cross-program compatibility checks +//! +//! The processor supports optimization hints (bump seeds and account lengths) while +//! maintaining strict security guarantees through canonical address validation. + +#![allow(unexpected_cfgs)] + +use { + crate::{account::create_pda_account, size::get_token_account_size}, + core::mem::MaybeUninit, + pinocchio::{ + account_info::AccountInfo, + cpi, + instruction::{AccountMeta, Instruction}, + program_error::ProgramError, + pubkey::{find_program_address, Pubkey}, + sysvars::{rent::Rent, Sysvar}, + ProgramResult, + }, + pinocchio_log::log, + pinocchio_pubkey::derive_address, + spl_token_interface::state::{ + account::Account as TokenAccount, mint::Mint, multisig::Multisig, Transmutable, + }, +}; + +#[cfg(target_os = "solana")] +use pinocchio::syscalls::sol_curve_validate_point; + +pub const INITIALIZE_ACCOUNT_3_DISCRIMINATOR: u8 = 18; +pub const INITIALIZE_IMMUTABLE_OWNER_DISCRIMINATOR: u8 = 22; +pub const TRANSFER_CHECKED_DISCRIMINATOR: u8 = 12; + +// Token-2022 AccountType::Account discriminator value +const ACCOUNTTYPE_ACCOUNT: u8 = 2; + +pub const INITIALIZE_IMMUTABLE_OWNER_DATA: [u8; 1] = [INITIALIZE_IMMUTABLE_OWNER_DISCRIMINATOR]; + +// Compile-time verifications +const _: () = assert!( + TokenAccount::LEN == 165, + "TokenAccount size changed unexpectedly" +); +const _: () = assert!(Multisig::LEN == 355, "Multisig size changed unexpectedly"); + +/// Parsed ATA accounts for create operations +pub struct CreateAccounts<'a> { + pub payer: &'a AccountInfo, + pub associated_token_account_to_create: &'a AccountInfo, + pub wallet: &'a AccountInfo, + pub mint: &'a AccountInfo, + pub system_program: &'a AccountInfo, + pub token_program: &'a AccountInfo, + pub rent_sysvar: Option<&'a AccountInfo>, +} + +/// Derive canonical ATA PDA from wallet, token program, and mint. +/// +/// This is the least efficient derivation method, as it searches from bump +/// 255 downward until an off-curve address is found. Use only when no bump hint +/// is available in the instruction data. +/// +/// An alternative was considered that used a loop with `derive_address` + +/// `is_off_curve` instead of `find_program_address`, but though it saved ~30 CUs +/// (1%) when bump happened to be `255`, it added more CUs on average. +/// +/// ## Returns +/// +/// `(address, bump)` - The canonical PDA address and its bump seed +#[inline(always)] +pub(crate) fn derive_canonical_ata_pda( + wallet: &Pubkey, + token_program: &Pubkey, + mint: &Pubkey, + program_id: &Pubkey, +) -> (Pubkey, u8) { + find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + program_id, + ) +} + +/// Check if the given program ID is SPL Token (not Token-2022) +#[inline(always)] +pub(crate) fn is_spl_token_program(program_id: &Pubkey) -> bool { + const SPL_TOKEN_PROGRAM_ID: Pubkey = + pinocchio_pubkey::pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + *program_id == SPL_TOKEN_PROGRAM_ID +} + +/// Check if account data represents an initialized token account. +/// Mimics p-token's is_initialized_account check. +/// +/// Panics if account_data.len() < 109. +#[inline(always)] +pub(crate) fn is_initialized_account(account_data: &[u8]) -> bool { + // Token account state is at offset 108 (after mint, owner, amount, delegate fields) + // State: 0 = Uninitialized, 1 = Initialized, 2 = Frozen + account_data[108] != 0 +} + +/// Validate that account data represents a valid token account. +/// Replicates Token-2022's GenericTokenAccount::valid_account_data checks. +#[inline(always)] +pub(crate) fn valid_token_account_data(account_data: &[u8]) -> bool { + // Regular Token account: exact length match and initialized + if account_data.len() == TokenAccount::LEN { + // SAFETY: TokenAccount::LEN is compile-ensured to be == 165 + return is_initialized_account(account_data); + } + + // Token-2022's GenericTokenAccount::valid_account_data assumes Multisig + // if account_data length is Multisig::LEN. Collisions are prevented by + // adding a byte if a token account happens to have the same length as + // Multisig::LEN. + if account_data.len() > TokenAccount::LEN { + if account_data.len() == Multisig::LEN { + return false; + } + // SAFETY: TokenAccount::LEN is compile-ensured to be == 165, and in + // this branch account_data.len > TokenAccount::LEN + if is_initialized_account(account_data) { + return account_data[TokenAccount::LEN] == ACCOUNTTYPE_ACCOUNT; + } + } + + false +} + +/// Get mint reference from account info +#[inline(always)] +pub(crate) fn get_decimals_from_mint(account: &AccountInfo) -> Result { + let mint_data_slice = account.try_borrow_data()?; + match unsafe { spl_token_interface::state::load_unchecked::(&mint_data_slice) } { + Ok(mint) => Ok(mint.decimals), + Err(err) => { + const MINT_BASE_SIZE: usize = core::mem::size_of::(); + log!( + "Error: Mint account data too small. Expected at least {} bytes, found {} bytes", + MINT_BASE_SIZE, + mint_data_slice.len() + ); + Err(err) + } + } +} + +/// Get token account reference with validation. Fails if a mutable borrow +/// of the account has occurred. +#[inline(always)] +pub(crate) fn load_token_account(account: &AccountInfo) -> Result<&TokenAccount, ProgramError> { + let account_data = account.try_borrow_data()?; + if !valid_token_account_data(&account_data) { + return Err(ProgramError::InvalidAccountData); + } + // SAFETY: We've validated the account data structure above + unsafe { Ok(&*(account_data.as_ptr() as *const TokenAccount)) } +} + +/// Get token account reference with validation. +/// SAFETY: Caller must ensure no mutable borrows of `account`. +#[inline(always)] +pub(crate) unsafe fn load_token_account_unchecked( + account: &AccountInfo, +) -> Result<&TokenAccount, ProgramError> { + let account_data = unsafe { account.borrow_data_unchecked() }; + + if !valid_token_account_data(account_data) { + return Err(ProgramError::InvalidAccountData); + } + + // SAFETY: We've validated the account data structure above + unsafe { Ok(&*(account_data.as_ptr() as *const TokenAccount)) } +} + +/// Validate token account owner matches expected owner +#[inline(always)] +pub(crate) fn validate_token_account_owner( + account: &TokenAccount, + expected_owner: &Pubkey, +) -> Result<(), ProgramError> { + if account.owner != *expected_owner { + log!( + "Error: Token account owner mismatch. Expected: {}, Found: {}", + expected_owner, + &account.owner + ); + return Err(ProgramError::IllegalOwner); + } + Ok(()) +} + +/// Validate token account mint matches expected mint +#[inline(always)] +pub(crate) fn validate_token_account_mint( + account: &TokenAccount, + expected_mint: &Pubkey, +) -> Result<(), ProgramError> { + if account.mint != *expected_mint { + log!( + "Error: Token account mint mismatch. Expected: {}, Found: {}", + expected_mint, + &account.mint + ); + return Err(ProgramError::InvalidAccountData); + } + Ok(()) +} + +/// Build InitializeAccount3 instruction data +#[inline(always)] +pub(crate) fn build_initialize_account3_data(owner: &Pubkey) -> [u8; 33] { + let mut data = MaybeUninit::<[u8; 33]>::uninit(); + let data_ptr = data.as_mut_ptr() as *mut u8; + // SAFETY: We initialize all 33 bytes before calling assume_init() + unsafe { + *data_ptr = INITIALIZE_ACCOUNT_3_DISCRIMINATOR; + core::ptr::copy_nonoverlapping(owner.as_ref().as_ptr(), data_ptr.add(1), 32); + data.assume_init() + } +} + +/// Build TransferChecked instruction data +#[inline(always)] +pub(crate) fn build_transfer_checked_data(amount: u64, decimals: u8) -> [u8; 10] { + let mut data = MaybeUninit::<[u8; 10]>::uninit(); + let data_ptr = data.as_mut_ptr() as *mut u8; + // SAFETY: We initialize all 10 bytes before calling assume_init() + unsafe { + *data_ptr = TRANSFER_CHECKED_DISCRIMINATOR; + core::ptr::copy_nonoverlapping(amount.to_le_bytes().as_ptr(), data_ptr.add(1), 8); + *data_ptr.add(9) = decimals; + data.assume_init() + } +} + +/// Parse and validate the standard Create account layout. +#[inline(always)] +pub(crate) fn parse_create_accounts( + accounts: &[AccountInfo], +) -> Result { + let [payer, associated_token_account_to_create, wallet, mint, system_program, token_program, maybe_rent_sysvar @ ..] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + Ok(CreateAccounts { + payer, + associated_token_account_to_create, + wallet, + mint, + system_program, + token_program, + rent_sysvar: maybe_rent_sysvar.first(), + }) +} + +/// Check if account already exists and is properly configured (idempotent check). +/// +/// This function validates that an existing ATA account: +/// 1. Is owned by the correct token program +/// 2. Has the correct owner (wallet) +/// 3. Has the correct mint +/// 4. Uses the canonical PDA address, even when `expected_bump` is provided +/// +/// ## Returns +/// +/// * `Ok(true)` - Account exists and is properly configured (safe to skip creation) +/// * `Ok(false)` - Account doesn't exist or is not token program owned (needs creation) +/// * `Err(_)` - Account exists but has invalid configuration (error condition) +/// +/// SAFETY: Caller must ensure no mutable borrows of `associated_token_account` have occurred. +#[inline(always)] +pub(crate) unsafe fn check_idempotent_account( + associated_token_account: &AccountInfo, + wallet: &AccountInfo, + mint_account: &AccountInfo, + token_program: &AccountInfo, + program_id: &Pubkey, + expected_bump: Option, +) -> Result { + if associated_token_account.is_owned_by(token_program.key()) { + // SAFETY: no mutable borrows of the associated_token_account have occurred in this + // function. Caller ensures that none have occurred in caller scope. + let ata_state = unsafe { load_token_account_unchecked(associated_token_account)? }; + + validate_token_account_owner(ata_state, wallet.key())?; + validate_token_account_mint(ata_state, mint_account.key())?; + + match expected_bump { + Some(bump) => { + let seeds: &[&[u8]; 3] = &[ + wallet.key().as_ref(), + token_program.key().as_ref(), + mint_account.key().as_ref(), + ]; + + // Check if a better canonical bump exists + reject_if_better_valid_bump_exists(seeds, program_id, bump)?; + + let maybe_canonical_address = derive_address::<3>(seeds, Some(bump), program_id); + + // We must check that the actual derived address is off-curve, + // since it will not fail downstream as in Create paths. + // Potential problem if skipping this is demonstrated in + // tests/bump/test_idemp_oncurve_attack.rs + if !is_off_curve(&maybe_canonical_address) { + log!( + "Error: Invalid bump: bump {} results in on curve address.", + bump, + ); + return Err(ProgramError::InvalidSeeds); + } + if maybe_canonical_address != *associated_token_account.key() { + log!( + "Error: Address mismatch: bump {} derives address which does not match provided associated token account address. Expected: {}, Found: {}", + bump, + &maybe_canonical_address, + associated_token_account.key() + ); + return Err(ProgramError::InvalidSeeds); + } + } + None => { + let (canonical_address, _bump) = derive_canonical_ata_pda( + wallet.key(), + token_program.key(), + mint_account.key(), + program_id, + ); + + if canonical_address != *associated_token_account.key() { + log!( + "Error: Address mismatch: derived associated token address does not match provided address. Expected: {}, Found: {}", + &canonical_address, + associated_token_account.key() + ); + return Err(ProgramError::InvalidSeeds); + } + } + } + + return Ok(true); + } + Ok(false) +} + +/// Determine the required space (in bytes) for the associated token account. +/// +/// Either uses a pre-computed account length hint or calls into the size +/// calculation logic to determine the space needed. For extended accounts, +/// passing in length can save significant compute units. +/// +/// ## Arguments +/// +/// * `known_token_account_len` - Optional pre-computed account length +/// +/// ## Returns +/// +/// The account size in bytes, or an error if size calculation fails. +#[inline(always)] +pub(crate) fn resolve_token_account_space( + token_program: &AccountInfo, + mint_account: &AccountInfo, + known_token_account_len: Option, +) -> Result { + match known_token_account_len { + Some(len) => Ok(len), + None => get_token_account_size(mint_account, token_program), + } +} + +/// Create and initialize an ATA account with the given bump seed. +#[allow(clippy::too_many_arguments)] +#[inline(always)] +pub(crate) fn create_and_initialize_ata( + payer: &AccountInfo, + associated_token_account: &AccountInfo, + wallet: &AccountInfo, + mint_account: &AccountInfo, + token_program: &AccountInfo, + rent: &Rent, + bump: u8, + space: usize, +) -> ProgramResult { + let bump_slice = &[bump]; + let seeds = pinocchio::seeds!( + wallet.key().as_ref(), + token_program.key().as_ref(), + mint_account.key().as_ref(), + bump_slice + ); + + create_pda_account( + payer, + rent, + space, + token_program.key(), + associated_token_account, + &seeds, + )?; + + // Initialize ImmutableOwner for non-SPL Token programs (future compatible) + if !is_spl_token_program(token_program.key()) { + let initialize_immutable_owner_metas = + &[AccountMeta::writable(associated_token_account.key())]; + let init_immutable_owner_ix = Instruction { + program_id: token_program.key(), + accounts: initialize_immutable_owner_metas, + data: &INITIALIZE_IMMUTABLE_OWNER_DATA, + }; + cpi::invoke(&init_immutable_owner_ix, &[associated_token_account])?; + } + + // Initialize account via InitializeAccount3. + let initialize_account_instr_data = build_initialize_account3_data(wallet.key()); + let initialize_account_metas = &[ + AccountMeta::writable(associated_token_account.key()), + AccountMeta::readonly(mint_account.key()), + ]; + let init_ix = Instruction { + program_id: token_program.key(), + accounts: initialize_account_metas, + data: &initialize_account_instr_data, + }; + + cpi::invoke(&init_ix, &[associated_token_account, mint_account]) +} + +/// Check if a given address is off-curve (not a valid Ed25519 curve point). +/// +/// Returns `true` if the address is off-curve, `false` if on-curve. +/// +/// - **On-chain (Solana)**: Uses `sol_curve_validate_point` syscall +/// - **Tests**: Uses curve25519-dalek to replicate on-chain behavior +/// - **Other builds**: Returns `false` +#[inline(always)] +#[allow(unused_variables)] +pub fn is_off_curve(address: &Pubkey) -> bool { + #[cfg(target_os = "solana")] + { + const ED25519_CURVE_ID: u64 = 0; + + let point_addr = address.as_ref().as_ptr(); + + // SAFETY: We're passing valid pointers to the syscall + // The syscall directly returns the validation result: + // - 0 means point is ON the curve (valid) + // - 1 means point is OFF the curve (invalid) + // - any other value means error + let syscall_result = unsafe { + sol_curve_validate_point(ED25519_CURVE_ID, point_addr, core::ptr::null_mut()) + }; + + syscall_result == 1 + } + #[cfg(all(not(target_os = "solana"), test))] + { + // Host build (tests, benches): replicate the on-chain `sol_curve_validate_point` logic + // using curve25519-dalek. A pubkey is "off-curve" if it cannot be decompressed into + // an Edwards point. + + curve25519_dalek::edwards::CompressedEdwardsY(*address) + .decompress() + .is_none() + } + #[cfg(all(not(target_os = "solana"), not(test)))] + { + false + } +} + +/// Validate an expected bump and ensure no better canonical bump exists. +/// +/// Given an expected bump, this function verifies that no higher bump value produces +/// a valid (off-curve) PDA address. This prevents creation of non-canonical ATAs +/// by rejecting sub-optimal bump seeds. +/// +/// ## Arguments +/// +/// * `seeds` - The PDA derivation seeds (wallet, token_program, mint) +/// * `program_id` - The program ID for PDA derivation +/// * `expected_bump` - The bump value provided by the caller +/// +/// ## Returns +/// +/// * `None` - No better bump exists, the expected_bump is canonical +/// * `Some((address, bump))` - A better bump was found, returns the canonical address and bump +/// +/// ## Security +/// +/// This function is critical for preventing PDA canonicality attacks. It ensures +/// that only the highest valid bump can be used, maintaining deterministic +/// address derivation across all clients. +#[inline(always)] +pub(crate) fn reject_if_better_valid_bump_exists( + seeds: &[&[u8]; 3], + program_id: &Pubkey, + expected_bump: u8, +) -> Result<(), ProgramError> { + // Optimization: Only verify no better bump exists. Don't require expected_bump to + // yield an off-curve address. This saves significant compute units while still + // preventing non-canonical addresses. + // + // Caller must ensure that `expected_bump` is off-curve, either via downstream failure + // (i.e. syscalls that will fail) or by calling `is_off_curve`. + let mut better_bump = 255; + while better_bump > expected_bump { + let maybe_better_address = derive_address::<3>(seeds, Some(better_bump), program_id); + if is_off_curve(&maybe_better_address) { + log!("Canonical address does not match provided address. Canonical bump is {}, with address {}.", better_bump, &maybe_better_address); + return Err(ProgramError::InvalidInstructionData); + } + better_bump -= 1; + } + Ok(()) +} + +/// Accounts: +/// [0] payer +/// [1] associated_token_account_to_create +/// [2] wallet +/// [3] mint +/// [4] system_program +/// [5] token_program +/// [6] rent_sysvar +/// +/// For Token-2022 accounts, create the account with the correct size +/// and call InitializeImmutableOwner followed by InitializeAccount3. +#[inline(always)] +pub(crate) fn process_create_associated_token_account( + program_id: &Pubkey, + create_accounts: &CreateAccounts, + expected_bump: Option, + known_token_account_len: Option, +) -> ProgramResult { + let bump = match expected_bump { + Some(provided_bump) => { + // Check if a better canonical bump exists + reject_if_better_valid_bump_exists( + &[ + create_accounts.wallet.key().as_ref(), + create_accounts.token_program.key().as_ref(), + create_accounts.mint.key().as_ref(), + ], + program_id, + provided_bump, + )?; + provided_bump + } + None => { + let (_address, computed_bump) = derive_canonical_ata_pda( + create_accounts.wallet.key(), + create_accounts.token_program.key(), + create_accounts.mint.key(), + program_id, + ); + computed_bump + } + }; + + let space = resolve_token_account_space( + create_accounts.token_program, + create_accounts.mint, + known_token_account_len, + )?; + + match create_accounts.rent_sysvar { + Some(rent_account) => { + let rent_ref = unsafe { Rent::from_account_info_unchecked(rent_account) }?; + create_and_initialize_ata( + create_accounts.payer, + create_accounts.associated_token_account_to_create, + create_accounts.wallet, + create_accounts.mint, + create_accounts.token_program, + rent_ref, + bump, + space, + ) + } + None => { + let rent = Rent::get()?; + create_and_initialize_ata( + create_accounts.payer, + create_accounts.associated_token_account_to_create, + create_accounts.wallet, + create_accounts.mint, + create_accounts.token_program, + &rent, + bump, + space, + ) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ata_mollusk_harness::validate_token_account_structure; + use core::ptr; + use std::vec::Vec; + use { + pinocchio::{program_error::ProgramError, pubkey::Pubkey}, + solana_keypair::Keypair, + solana_program::pubkey::Pubkey as SolanaPubkey, + solana_signer::Signer, + spl_token_interface::state::{ + account::Account as TokenAccount, multisig::Multisig, Transmutable, + }, + std::{collections::HashSet, vec}, + }; + + // Test utility functions + fn create_token_account_data(mint: &Pubkey, owner: &Pubkey, amount: u64) -> Vec { + let mut data = vec![0u8; TokenAccount::LEN]; + + // Set mint (bytes 0-31) + data[0..32].copy_from_slice(mint.as_ref()); + + // Set owner (bytes 32-63) + data[32..64].copy_from_slice(owner.as_ref()); + + // Set amount (bytes 64-71) + data[64..72].copy_from_slice(&amount.to_le_bytes()); + + // Set initialized state (byte 108) + data[108] = 1; + + data + } + + #[test] + fn test_is_off_curve_true() { + let program_id = SolanaPubkey::new_unique(); + let seeds = &[b"test_seed" as &[u8]]; + let (off_curve_address, _) = SolanaPubkey::find_program_address(seeds, &program_id); + let pinocchio_format = Pubkey::from(off_curve_address.to_bytes()); + let result = is_off_curve(&pinocchio_format); + assert!(result); + } + + #[test] + fn test_is_off_curve_false() { + // Generate a random address + let wallet = Keypair::new(); + let address = wallet.pubkey(); + let pinocchio_format = Pubkey::from(address.to_bytes()); + let result = is_off_curve(&pinocchio_format); + assert!(!result); + } + + #[test] + fn test_valid_token_account_data() { + // Case 1: Regular, initialized account + let mut data1 = [0u8; TokenAccount::LEN]; + data1[108] = 1; // initialized state + assert!( + valid_token_account_data(&data1), + "Regular initialized account should be valid" + ); + + // Case 2: Uninitialized account + let mut data2 = [0u8; TokenAccount::LEN]; + data2[108] = 0; // uninitialized state + assert!( + !valid_token_account_data(&data2), + "Uninitialized account should be invalid" + ); + + // Case 3: Data too short + let data3 = [0u8; TokenAccount::LEN - 1]; + assert!( + !valid_token_account_data(&data3), + "Data shorter than TokenAccount::LEN should be invalid" + ); + + // Case 4: Extended, correctly typed account + let mut data4 = vec![0u8; TokenAccount::LEN + 10]; + data4[108] = 1; // initialized + data4[TokenAccount::LEN] = 2; // AccountType::Account + assert!( + valid_token_account_data(&data4), + "Extended, correctly typed account should be valid" + ); + + // Case 5: Extended, incorrectly typed account + let mut data5 = vec![0u8; TokenAccount::LEN + 10]; + data5[108] = 1; // initialized + data5[TokenAccount::LEN] = 1; // Wrong account type + assert!( + !valid_token_account_data(&data5), + "Extended, incorrectly typed account should be invalid" + ); + + // Case 6: Multisig collision + let mut data6 = [0u8; Multisig::LEN]; + data6[0] = 2; // valid multisig m + data6[1] = 3; // valid multisig n + data6[2] = 1; // initialized + data6[108] = 1; + assert!( + !valid_token_account_data(&data6), + "Multisig data should be invalid" + ); + } + + #[test] + fn test_validate_token_account_owner() { + let owner1 = Pubkey::from([1u8; 32]); + let owner2 = Pubkey::from([2u8; 32]); + let mint = Pubkey::from([3u8; 32]); + let data = create_token_account_data(&mint, &owner1, 1000); + let account: &TokenAccount = unsafe { &*(data.as_ptr() as *const TokenAccount) }; + + assert!(validate_token_account_owner(account, &owner1).is_ok()); + assert_eq!( + validate_token_account_owner(account, &owner2).unwrap_err(), + ProgramError::IllegalOwner + ); + } + + #[test] + fn test_validate_token_account_mint() { + let mint1 = Pubkey::from([1u8; 32]); + let mint2 = Pubkey::from([2u8; 32]); + let owner = Pubkey::from([3u8; 32]); + let data = create_token_account_data(&mint1, &owner, 1000); + let account: &TokenAccount = unsafe { &*(data.as_ptr() as *const TokenAccount) }; + + assert!(validate_token_account_mint(account, &mint1).is_ok()); + assert_eq!( + validate_token_account_mint(account, &mint2).unwrap_err(), + ProgramError::InvalidAccountData + ); + } + + #[test] + fn test_create_token_account_data_structure() { + let mint = Pubkey::from([1u8; 32]); + let owner = Pubkey::from([2u8; 32]); + let amount = 1000u64; + + let data = create_token_account_data(&mint, &owner, amount); + + assert!(validate_token_account_structure(&data, &mint, &owner)); + assert!(valid_token_account_data(&data)); + } + + #[test] + fn test_build_initialize_account3_data_basic() { + let owner = Pubkey::from([1u8; 32]); + let data = build_initialize_account3_data(&owner); + + assert_eq!(data.len(), 33); + assert_eq!(data[0], INITIALIZE_ACCOUNT_3_DISCRIMINATOR); + assert_eq!(&data[1..33], owner.as_ref()); + } + + #[test] + fn test_build_initialize_account3_data_different_owners() { + let owner1 = Pubkey::from([1u8; 32]); + let owner2 = Pubkey::from([2u8; 32]); + + let data1 = build_initialize_account3_data(&owner1); + let data2 = build_initialize_account3_data(&owner2); + + assert_eq!(data1[0], data2[0]); // Same discriminator + assert_ne!(&data1[1..], &data2[1..]); // Different owner bytes + } + + #[test] + fn test_build_transfer_data_basic() { + let amount = 1000u64; + let decimals = 6u8; + let data = build_transfer_checked_data(amount, decimals); + + assert_eq!(data.len(), 10); + assert_eq!(data[0], TRANSFER_CHECKED_DISCRIMINATOR); + + let parsed_amount = u64::from_le_bytes([ + data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], + ]); + assert_eq!(parsed_amount, amount); + assert_eq!(data[9], decimals); + } + + #[test] + fn test_build_transfer_data_edge_cases() { + // Test zero values + let data = build_transfer_checked_data(0, 0); + assert_eq!(data.len(), 10); + assert_eq!(data[0], TRANSFER_CHECKED_DISCRIMINATOR); + assert_eq!( + u64::from_le_bytes([ + data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] + ]), + 0 + ); + assert_eq!(data[9], 0); + + // Test max values + let data = build_transfer_checked_data(u64::MAX, u8::MAX); + assert_eq!(data.len(), 10); + assert_eq!(data[0], TRANSFER_CHECKED_DISCRIMINATOR); + assert_eq!( + u64::from_le_bytes([ + data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8] + ]), + u64::MAX + ); + assert_eq!(data[9], u8::MAX); + } + + #[test] + fn test_build_transfer_data_endianness() { + let amount = 0x0123456789abcdef_u64; + let decimals = 6u8; + let data = build_transfer_checked_data(amount, decimals); + + // Verify little-endian encoding + let expected_bytes = amount.to_le_bytes(); + assert_eq!(&data[1..9], &expected_bytes); + } + + #[test] + fn test_instruction_data_deterministic() { + let owner = Pubkey::from([42u8; 32]); + let amount = 1000u64; + let decimals = 6u8; + + // Test that identical inputs produce identical outputs + let data1 = build_initialize_account3_data(&owner); + let data2 = build_initialize_account3_data(&owner); + assert_eq!(data1, data2); + + let transfer1 = build_transfer_checked_data(amount, decimals); + let transfer2 = build_transfer_checked_data(amount, decimals); + assert_eq!(transfer1, transfer2); + } + + #[test] + fn test_discriminator_uniqueness() { + use crate::recover::CLOSE_ACCOUNT_DISCRIMINATOR; + + let discriminators = [ + INITIALIZE_ACCOUNT_3_DISCRIMINATOR, + INITIALIZE_IMMUTABLE_OWNER_DISCRIMINATOR, + TRANSFER_CHECKED_DISCRIMINATOR, + CLOSE_ACCOUNT_DISCRIMINATOR, + ]; + + let mut unique_discriminators = HashSet::new(); + for &d in &discriminators { + unique_discriminators.insert(d); + } + + assert_eq!( + discriminators.len(), + unique_discriminators.len(), + "All discriminators must be unique" + ); + } + + // Test utility - AccountLayout structure for creating test accounts + #[repr(C)] + struct AccountLayout { + borrow_state: u8, + is_signer: u8, + is_writable: u8, + executable: u8, + resize_delta: u32, + key: Pubkey, + owner: Pubkey, + lamports: u64, + data_len: u64, + } + + fn with_test_accounts_for_parsing(count: usize, test_fn: F) -> R + where + F: FnOnce(&[AccountInfo]) -> R, + { + let mut account_data: Vec = (0..count) + .map(|i| AccountLayout { + borrow_state: 0b_1111_1111, + is_signer: 0, + is_writable: 0, + executable: 0, + resize_delta: 0, + key: Pubkey::from([i as u8; 32]), + owner: Pubkey::from([(i as u8).wrapping_add(1); 32]), + lamports: 0, + data_len: 0, + }) + .collect(); + + let account_infos: Vec = account_data + .iter_mut() + .map(|layout| unsafe { std::mem::transmute::<*mut AccountLayout, AccountInfo>(layout) }) + .collect(); + + test_fn(&account_infos) + } + + #[test] + fn test_parse_create_accounts_success_without_rent() { + // Exactly 6 accounts – rent sysvar should be `None`. + with_test_accounts_for_parsing(6, |accounts| { + let parsed = parse_create_accounts(accounts).unwrap(); + + assert!(ptr::eq(parsed.payer, &accounts[0])); + assert_eq!(parsed.payer.key(), accounts[0].key()); + assert!(ptr::eq( + parsed.associated_token_account_to_create, + &accounts[1] + )); + assert_eq!( + parsed.associated_token_account_to_create.key(), + accounts[1].key() + ); + assert!(ptr::eq(parsed.wallet, &accounts[2])); + assert_eq!(parsed.wallet.key(), accounts[2].key()); + assert!(ptr::eq(parsed.mint, &accounts[3])); + assert_eq!(parsed.mint.key(), accounts[3].key()); + assert!(ptr::eq(parsed.system_program, &accounts[4])); + assert_eq!(parsed.system_program.key(), accounts[4].key()); + assert!(ptr::eq(parsed.token_program, &accounts[5])); + assert_eq!(parsed.token_program.key(), accounts[5].key()); + assert!(parsed.rent_sysvar.is_none()); + }); + } + + #[test] + fn test_parse_create_accounts_success_with_rent() { + // 7 accounts – index 6 is rent sysvar. + with_test_accounts_for_parsing(7, |accounts| { + assert_eq!(accounts.len(), 7); + + let parsed = parse_create_accounts(accounts).unwrap(); + + assert!(parsed.rent_sysvar.is_some()); + assert!(ptr::eq(parsed.rent_sysvar.unwrap(), &accounts[6])); + assert_eq!(parsed.rent_sysvar.unwrap().key(), accounts[6].key()); + }); + } + + #[test] + fn test_parse_create_accounts_error_insufficient() { + with_test_accounts_for_parsing(5, |accounts| { + assert!(matches!( + parse_create_accounts(accounts), + Err(ProgramError::NotEnoughAccountKeys) + )); + }); + } + + #[test] + fn test_fn_is_spl_token_program() { + assert!(is_spl_token_program(&spl_token_interface::program::id())); + + let token_2022_id = + pinocchio_pubkey::pubkey!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); + assert!(!is_spl_token_program(&token_2022_id)); + } +} diff --git a/p-ata/src/recover.rs b/p-ata/src/recover.rs new file mode 100644 index 00000000..7cb8ddd5 --- /dev/null +++ b/p-ata/src/recover.rs @@ -0,0 +1,367 @@ +//! Processor and helpers related only to `RecoverNested` operations. + +use { + crate::processor::{ + build_transfer_checked_data, derive_canonical_ata_pda, get_decimals_from_mint, + load_token_account, + }, + pinocchio::{ + account_info::AccountInfo, + cpi::invoke_signed, + instruction::{AccountMeta, Instruction, Seed, Signer}, + msg, + program_error::ProgramError, + pubkey::Pubkey, + ProgramResult, + }, + pinocchio_log::log, + spl_token_interface::state::multisig::{Multisig, MAX_SIGNERS}, +}; + +pub const CLOSE_ACCOUNT_DISCRIMINATOR: u8 = 9; +pub const CLOSE_ACCOUNT_DATA: [u8; 1] = [CLOSE_ACCOUNT_DISCRIMINATOR]; + +/// Parsed Recover accounts for recover operations +pub struct RecoverNestedAccounts<'a> { + pub nested_associated_token_account: &'a AccountInfo, + pub nested_mint: &'a AccountInfo, + pub destination_associated_token_account: &'a AccountInfo, + pub owner_associated_token_account: &'a AccountInfo, + pub owner_mint: &'a AccountInfo, + pub wallet: &'a AccountInfo, + pub token_program: &'a AccountInfo, +} + +/// Parse and validate the standard Recover account layout. +#[inline(always)] +pub(crate) fn parse_recover_accounts( + accounts: &[AccountInfo], +) -> Result { + if accounts.len() < 7 { + return Err(ProgramError::NotEnoughAccountKeys); + } + + // SAFETY: account len already checked + unsafe { + Ok(RecoverNestedAccounts { + nested_associated_token_account: accounts.get_unchecked(0), + nested_mint: accounts.get_unchecked(1), + destination_associated_token_account: accounts.get_unchecked(2), + owner_associated_token_account: accounts.get_unchecked(3), + owner_mint: accounts.get_unchecked(4), + wallet: accounts.get_unchecked(5), + token_program: accounts.get_unchecked(6), + }) + } +} + +/// Transfer all tokens from a nested associated token account (an ATA created +/// with another ATA as the wallet) to the canonical ATA and then closes the +/// nested account to recover rent. +/// +/// ## Account Layout +/// ```ignore +/// [0] nested_associated_token_account (writable) - source account to drain +/// [1] nested_mint - mint of tokens being recovered +/// [2] destination_associated_token_account (writable) - canonical destination ATA +/// [3] owner_associated_token_account - ATA that "owns" the nested ATA +/// [4] owner_mint - mint for the owner ATA +/// [5] wallet (signer) - ultimate owner wallet +/// [6] token_program - token program for operations +/// [7..] multisig signer accounts (signers) - if wallet is multisig +/// ``` +/// +/// - The owner ATA must properly derive the nested ATA +/// - The wallet must properly derive the owner ATA and destination ATA +/// - The nested mint must properly derive the nested ATA and destination ATA +pub(crate) fn process_recover_nested( + program_id: &Pubkey, + accounts: &[AccountInfo], +) -> ProgramResult { + let recover_accounts = parse_recover_accounts(accounts)?; + + let (owner_associated_token_address, owner_bump) = derive_canonical_ata_pda( + recover_accounts.wallet.key(), + recover_accounts.token_program.key(), + recover_accounts.owner_mint.key(), + program_id, + ); + + if owner_associated_token_address != *recover_accounts.owner_associated_token_account.key() { + msg!("Error: Owner associated address does not match seed derivation"); + return Err(ProgramError::InvalidSeeds); + } + + let (nested_associated_token_address, _) = derive_canonical_ata_pda( + recover_accounts.owner_associated_token_account.key(), + recover_accounts.token_program.key(), + recover_accounts.nested_mint.key(), + program_id, + ); + + if nested_associated_token_address != *recover_accounts.nested_associated_token_account.key() { + msg!("Error: Nested associated address does not match seed derivation"); + return Err(ProgramError::InvalidSeeds); + } + + let (destination_associated_token_address, _) = derive_canonical_ata_pda( + recover_accounts.wallet.key(), + recover_accounts.token_program.key(), + recover_accounts.nested_mint.key(), + program_id, + ); + + if destination_associated_token_address + != *recover_accounts.destination_associated_token_account.key() + { + msg!("Error: Destination associated address does not match seed derivation"); + return Err(ProgramError::InvalidSeeds); + } + + // Validate that the owner ATA exists and is a valid token account + let _owner_token_account = load_token_account(recover_accounts.owner_associated_token_account)?; + + // Handle multisig case + if !recover_accounts.wallet.is_signer() { + // Multisig case: must be token-program owned + if !recover_accounts + .wallet + .is_owned_by(recover_accounts.token_program.key()) + { + log!( + "Error: Multisig wallet {} is not owned by token program {}", + recover_accounts.wallet.key(), + recover_accounts.token_program.key() + ); + return Err(ProgramError::MissingRequiredSignature); + } + + let wallet_data_slice = unsafe { recover_accounts.wallet.borrow_data_unchecked() }; + let multisig_state: &Multisig = unsafe { + spl_token_interface::state::load::(wallet_data_slice) + .map_err(|_| ProgramError::InvalidAccountData)? + }; + + let signer_infos = &accounts[7..]; + + let mut num_signers = 0; + let mut matched = [false; MAX_SIGNERS as usize]; + + for signer in signer_infos.iter() { + for (position, key) in multisig_state.signers[0..multisig_state.n as usize] + .iter() + .enumerate() + { + if key == signer.key() && !matched[position] { + if !signer.is_signer() { + log!( + "Error: Multisig member account {} is not a signer", + signer.key() + ); + return Err(ProgramError::MissingRequiredSignature); + } + matched[position] = true; + num_signers += 1; + } + } + } + + if num_signers < multisig_state.m { + log!( + "Error: Insufficient multisig signatures. Required: {}, Found: {}", + multisig_state.m, + num_signers + ); + return Err(ProgramError::MissingRequiredSignature); + } + } + + let amount_to_recover = + load_token_account(recover_accounts.nested_associated_token_account)?.amount(); + + let nested_mint_decimals = get_decimals_from_mint(recover_accounts.nested_mint)?; + + let transfer_data = build_transfer_checked_data(amount_to_recover, nested_mint_decimals); + + let transfer_metas = &[ + AccountMeta { + pubkey: recover_accounts.nested_associated_token_account.key(), + is_writable: true, + is_signer: false, + }, + AccountMeta { + pubkey: recover_accounts.nested_mint.key(), + is_writable: false, + is_signer: false, + }, + AccountMeta { + pubkey: recover_accounts.destination_associated_token_account.key(), + is_writable: true, + is_signer: false, + }, + AccountMeta { + pubkey: recover_accounts.owner_associated_token_account.key(), + is_writable: false, + is_signer: true, + }, + ]; + + let ix_transfer = Instruction { + program_id: recover_accounts.token_program.key(), + accounts: transfer_metas, + data: &transfer_data, + }; + + let owner_bump_slice = [owner_bump]; + let pda_seed_array: [Seed<'_>; 4] = [ + Seed::from(recover_accounts.wallet.key().as_ref()), + Seed::from(recover_accounts.token_program.key().as_ref()), + Seed::from(recover_accounts.owner_mint.key().as_ref()), + Seed::from(&owner_bump_slice[..]), + ]; + let pda_signer = Signer::from(&pda_seed_array); + + invoke_signed( + &ix_transfer, + &[ + recover_accounts.nested_associated_token_account, + recover_accounts.nested_mint, + recover_accounts.destination_associated_token_account, + recover_accounts.owner_associated_token_account, + ], + &[pda_signer.clone()], + )?; + + let close_metas = &[ + AccountMeta { + pubkey: recover_accounts.nested_associated_token_account.key(), + is_writable: true, + is_signer: false, + }, + AccountMeta { + pubkey: recover_accounts.wallet.key(), + is_writable: true, + is_signer: false, + }, + AccountMeta { + pubkey: recover_accounts.owner_associated_token_account.key(), + is_writable: false, + is_signer: true, + }, + ]; + + let ix_close = Instruction { + program_id: recover_accounts.token_program.key(), + accounts: close_metas, + data: &CLOSE_ACCOUNT_DATA, + }; + + invoke_signed( + &ix_close, + &[ + recover_accounts.nested_associated_token_account, + recover_accounts.wallet, + recover_accounts.owner_associated_token_account, + ], + &[pda_signer], + )?; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use { + pinocchio::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}, + std::{ptr, vec::Vec}, + }; + + // Test utility - AccountLayout structure for creating test accounts + #[repr(C)] + struct AccountLayout { + borrow_state: u8, + is_signer: u8, + is_writable: u8, + executable: u8, + resize_delta: u32, + key: Pubkey, + owner: Pubkey, + lamports: u64, + data_len: u64, + } + + fn with_test_accounts(count: usize, test_fn: F) -> R + where + F: FnOnce(&[AccountInfo]) -> R, + { + let mut account_data: Vec = (0..count) + .map(|i| AccountLayout { + borrow_state: 0b_1111_1111, + is_signer: 0, + is_writable: 0, + executable: 0, + resize_delta: 0, + key: Pubkey::from([i as u8; 32]), + owner: Pubkey::from([(i as u8).wrapping_add(1); 32]), + lamports: 0, + data_len: 0, + }) + .collect(); + + let account_infos: Vec = account_data + .iter_mut() + .map(|layout| unsafe { std::mem::transmute::<*mut AccountLayout, AccountInfo>(layout) }) + .collect(); + + test_fn(&account_infos) + } + + #[test] + fn test_parse_recover_accounts_success() { + with_test_accounts(7, |accounts| { + assert_eq!(accounts.len(), 7); + + let parsed = parse_recover_accounts(accounts).unwrap(); + + assert!(ptr::eq( + parsed.nested_associated_token_account, + &accounts[0] + )); + assert_eq!( + parsed.nested_associated_token_account.key(), + accounts[0].key() + ); + assert!(ptr::eq(parsed.nested_mint, &accounts[1])); + assert_eq!(parsed.nested_mint.key(), accounts[1].key()); + assert!(ptr::eq( + parsed.destination_associated_token_account, + &accounts[2] + )); + assert_eq!( + parsed.destination_associated_token_account.key(), + accounts[2].key() + ); + assert!(ptr::eq(parsed.owner_associated_token_account, &accounts[3])); + assert_eq!( + parsed.owner_associated_token_account.key(), + accounts[3].key() + ); + assert!(ptr::eq(parsed.owner_mint, &accounts[4])); + assert_eq!(parsed.owner_mint.key(), accounts[4].key()); + assert!(ptr::eq(parsed.wallet, &accounts[5])); + assert_eq!(parsed.wallet.key(), accounts[5].key()); + assert!(ptr::eq(parsed.token_program, &accounts[6])); + assert_eq!(parsed.token_program.key(), accounts[6].key()); + }); + } + + #[test] + fn test_parse_recover_accounts_error_insufficient() { + with_test_accounts(6, |accounts| { + assert!(matches!( + parse_recover_accounts(accounts), + Err(ProgramError::NotEnoughAccountKeys) + )); + }); + } +} diff --git a/p-ata/src/size.rs b/p-ata/src/size.rs new file mode 100644 index 00000000..c4d3ebaf --- /dev/null +++ b/p-ata/src/size.rs @@ -0,0 +1,767 @@ +//! Helpers for determining the necessary associated token account data length. +//! +//! In particular, this module provides efficient account size calculation for +//! extended mints by: +//! +//! 1. **Inline Extension Parsing**: For Token-2022, analyzes mint extension data +//! directly to compute required account extensions, avoiding expensive CPI +//! calls when possible +//! 2. **Fallback CPI**: Uses GetAccountDataSize instruction for unknown extensions +//! or non-Token-2022 programs. Clients in these situations can always pass in +//! the account data length in instruction data to avoid excess compute. + +use pinocchio::{ + account_info::AccountInfo, + cpi, + instruction::{AccountMeta, Instruction}, + program_error::ProgramError, + pubkey::Pubkey, +}; +use pinocchio_log::log; + +use crate::processor::is_spl_token_program; + +pub const GET_ACCOUNT_DATA_SIZE_DISCRIMINATOR: u8 = 21; +pub const MINT_BASE_SIZE: usize = 82; +pub const TOKEN_ACCOUNT_SIZE: usize = 165; + +// These constants are taken from the Token-2022 ExtensionType enum. +// Tests verify the constants are in sync without pulling in spl-token-2022 +// as a non-dev dependency. +pub const EXTENSION_TRANSFER_FEE_CONFIG: u16 = 1; +pub const EXTENSION_NON_TRANSFERABLE: u16 = 9; +pub const EXTENSION_TRANSFER_HOOK: u16 = 14; +pub const EXTENSION_PAUSABLE: u16 = 26; +pub const EXTENSION_PLANNED_ZERO_ACCOUNT_DATA_LENGTH_EXTENSION: u16 = 28; + +/// Check if the given program ID is Token-2022 +#[inline(always)] +pub(crate) fn is_spl_token_2022_program(program_id: &Pubkey) -> bool { + const TOKEN_2022_PROGRAM_ID: Pubkey = + pinocchio_pubkey::pubkey!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"); + *program_id == TOKEN_2022_PROGRAM_ID +} + +/// Calculate token account size by parsing mint extension data inline. +/// +/// ## Returns +/// +/// - `Some(size)` - Successfully calculated account size in bytes +/// - `None` - Unknown extension found, caller should fall back to CPI +#[inline(always)] +pub(crate) fn calculate_account_size_from_mint_extensions(mint_data: &[u8]) -> Option { + const ACCOUNT_TYPE_OFFSET: usize = TOKEN_ACCOUNT_SIZE; + const BASE_TOKEN_2022_ACCOUNT_SIZE: usize = TOKEN_ACCOUNT_SIZE + 5; + + // Invalid/failed mint creation + if mint_data.is_empty() { + return None; + } + + // Fast-path: no mint extensions → no additional account extensions either. + if mint_data.len() <= ACCOUNT_TYPE_OFFSET { + return Some(BASE_TOKEN_2022_ACCOUNT_SIZE); + } + + let data_len = mint_data.len(); + let mut account_extensions_size = 0usize; + // Start cursor after the account-type discriminator byte + let mut cursor = ACCOUNT_TYPE_OFFSET + 1; + + while cursor + 4 <= data_len { + // Read 4-byte TLV header (little-endian: [type: u16 | length: u16]) + // Avoiding u32::from_le_bytes() here saves about 6 compute units in the + // `create_extended` bench. + // + // SAFETY: cursor is always verified to be within the slice before deref + // in the `while` loop condition. + let header = + unsafe { core::ptr::read_unaligned(mint_data.as_ptr().add(cursor) as *const u32) }; + let extension_type_raw = (header & 0xFFFF) as u16; + let length = (header >> 16) as u16; + + // TypeEnd / Uninitialized ends the TLV list + if extension_type_raw == 0 { + break; + } + + // Based on token-2022's get_required_init_account_extensions + match extension_type_raw { + EXTENSION_TRANSFER_FEE_CONFIG => { + // TransferFeeConfig → needs TransferFeeAmount (8 bytes data + 4 TLV) + account_extensions_size += 4 + 8; + } + EXTENSION_NON_TRANSFERABLE => { + // NonTransferable → NonTransferableAccount (0 bytes data + 4 TLV) + account_extensions_size += 4; + } + EXTENSION_TRANSFER_HOOK => { + // TransferHook → TransferHookAccount (1 byte data + 4 TLV) + account_extensions_size += 4 + 1; + } + EXTENSION_PAUSABLE => { + // Pausable → PausableAccount (0 bytes data + 4 TLV) + account_extensions_size += 4; + } + // All other known extensions + discriminant + if discriminant <= EXTENSION_PLANNED_ZERO_ACCOUNT_DATA_LENGTH_EXTENSION => + { + // No account-side data required + } + // Unknown extension + _ => { + return None; + } + } + + cursor += 4 + length as usize; + } + + Some(BASE_TOKEN_2022_ACCOUNT_SIZE + account_extensions_size) +} + +/// Get the required account size for a mint using inline parsing first, +/// falling back to GetAccountDataSize CPI only when necessary. +/// Returns the account size in bytes. +#[inline(always)] +pub(crate) fn get_token_account_size( + mint_account: &AccountInfo, + token_program: &AccountInfo, +) -> Result { + if is_spl_token_program(token_program.key()) { + return Ok(TOKEN_ACCOUNT_SIZE); + } + + // Token mint has no extensions other than ImmutableOwner + // Note: This assumes future token programs include ImmutableOwner extension. + if !token_mint_has_extensions(mint_account) { + return Ok(TOKEN_ACCOUNT_SIZE + 5); + } + + if is_spl_token_2022_program(token_program.key()) { + // The mint_data is not verified to be mint data here; the authoritative check + // is the token program's mint validation during initialization, invoked in + // `create_and_initialize_ata()`. + // + // SAFETY: This is the only place in this function that borrows mint_account data, + // and the borrow is released when mint_data goes out of scope before any other + // operations. + let mint_data = unsafe { mint_account.borrow_data_unchecked() }; + if let Some(size) = calculate_account_size_from_mint_extensions(mint_data) { + return Ok(size); + } + } + + // Fallback to CPI for unknown/variable-length extensions or unknown token programs + // ImmutableOwner extension is required for Token-2022 Associated Token Accounts + const INSTRUCTION_DATA: [u8; 3] = [GET_ACCOUNT_DATA_SIZE_DISCRIMINATOR, 7u8, 0u8]; // [7, 0] = ImmutableOwner as u16 + + let get_size_metas = &[AccountMeta { + pubkey: mint_account.key(), + is_writable: false, + is_signer: false, + }]; + + let get_size_ix = Instruction { + program_id: token_program.key(), + accounts: get_size_metas, + data: &INSTRUCTION_DATA, + }; + + cpi::invoke(&get_size_ix, &[mint_account])?; + let return_data = cpi::get_return_data().ok_or_else(|| { + log!( + "Error: Token program {} did not return account size data for mint {}", + token_program.key(), + mint_account.key() + ); + ProgramError::InvalidAccountData + })?; + + // `try_into` as this could be an unknown token program; + // it must error if it doesn't give us [u8; 8] + Ok(u64::from_le_bytes( + return_data + .as_slice() + .try_into() + .map_err(|_| { + log!( + "Error: Token program {} returned invalid account size data. Expected 8 bytes, got {} bytes", + token_program.key(), + return_data.as_slice().len() + ); + ProgramError::InvalidAccountData + })?, + ) as usize) +} + +/// Check if a Token-2022 mint has extensions by examining its data length +#[inline(always)] +pub(crate) fn token_mint_has_extensions(mint_account: &AccountInfo) -> bool { + // If mint data is larger than base, it has extensions + mint_account.data_len() > MINT_BASE_SIZE +} + +#[cfg(test)] +mod tests { + use super::*; + use spl_token_2022::extension::ExtensionType; + use std::vec; + + // Test that the constants in this crate match the constants in the Token-2022 + // ExtensionType enum. Avoids pulling in spl-token-2022 or upcoming interface + // as a non-dev dependency. + #[test] + fn test_extension_constants_match_token_2022() { + // Prevent drift between these Token-2022 ExtensionType enum values + assert_eq!( + EXTENSION_TRANSFER_FEE_CONFIG, + ExtensionType::TransferFeeConfig as u16, + "TransferFeeConfig constant mismatch" + ); + + assert_eq!( + EXTENSION_NON_TRANSFERABLE, + ExtensionType::NonTransferable as u16, + "NonTransferable constant mismatch" + ); + + assert_eq!( + EXTENSION_TRANSFER_HOOK, + ExtensionType::TransferHook as u16, + "TransferHook constant mismatch" + ); + + assert_eq!( + EXTENSION_PAUSABLE, + ExtensionType::Pausable as u16, + "Pausable constant mismatch" + ); + } + + #[test] + fn test_planned_extension_is_next_after_last_deployed_extension() { + let last_real_extension = ExtensionType::PausableAccount as u16; + + assert_eq!( + EXTENSION_PLANNED_ZERO_ACCOUNT_DATA_LENGTH_EXTENSION, + last_real_extension + 1, + "Planned extension should be exactly one more than PausableAccount ({})", + last_real_extension + ); + } + + use { + spl_token_2022::extension::{ + default_account_state::DefaultAccountState, group_pointer::GroupPointer, + interest_bearing_mint::InterestBearingConfig, metadata_pointer::MetadataPointer, + mint_close_authority::MintCloseAuthority, non_transferable::NonTransferable, + pausable::PausableConfig, permanent_delegate::PermanentDelegate, + transfer_fee::TransferFeeConfig, transfer_hook::TransferHook, + PodStateWithExtensionsMut, + }, + spl_token_2022::pod::PodMint, + spl_token_group_interface::state::{TokenGroup, TokenGroupMember}, + spl_token_metadata_interface::state::TokenMetadata, + std::{string::String, vec::Vec}, + }; + + /// Create mint data with specific extensions using token-2022's official methods + pub fn create_mint_data_with_extensions(extension_types: &[ExtensionType]) -> Vec { + use spl_token_2022::extension::{BaseStateWithExtensionsMut, ExtensionType}; + + let required_size = if extension_types + .iter() + .any(|ext| matches!(ext, ExtensionType::TokenMetadata)) + { + // Calculate length for all sized extensions first, then add buffer for TokenMetadata + let mut size = ExtensionType::try_calculate_account_len::( + &extension_types + .iter() + .copied() + .filter(|e| !matches!(e, ExtensionType::TokenMetadata)) + .collect::>(), + ) + .expect("calc len for sized subset"); + + const TOKEN_METADATA_VALUE_LEN_ESTIMATE: usize = 500; + size += TOKEN_METADATA_VALUE_LEN_ESTIMATE + 4; // value + TLV header + size + } else { + ExtensionType::try_calculate_account_len::(extension_types) + .expect("Failed to calculate account length") + }; + + let mut data = vec![0u8; required_size]; + + let mut mint = match PodStateWithExtensionsMut::::unpack_uninitialized(&mut data) { + Ok(mint) => mint, + Err(e) => panic!( + "Failed to unpack mint for extensions {:?}: {:?}", + extension_types, e + ), + }; + + mint.base.mint_authority = Default::default(); + mint.base.supply = 0u64.into(); + mint.base.decimals = 6; + mint.base.is_initialized = true.into(); + mint.base.freeze_authority = Default::default(); + + for extension_type in extension_types { + match extension_type { + ExtensionType::TransferFeeConfig => { + let extension = mint + .init_extension::(true) + .expect("Failed to init TransferFeeConfig"); + extension.transfer_fee_config_authority = Default::default(); + extension.withdraw_withheld_authority = Default::default(); + extension.withheld_amount = 0u64.into(); + } + ExtensionType::NonTransferable => { + mint.init_extension::(true) + .expect("Failed to init NonTransferable"); + } + ExtensionType::TransferHook => { + let extension = mint + .init_extension::(true) + .expect("Failed to init TransferHook"); + extension.authority = Default::default(); + extension.program_id = Default::default(); + } + ExtensionType::Pausable => { + let extension = mint + .init_extension::(true) + .expect("Failed to init PausableConfig"); + extension.authority = Default::default(); + extension.paused = false.into(); + } + ExtensionType::DefaultAccountState => { + let extension = mint + .init_extension::(true) + .expect("Failed to init DefaultAccountState"); + extension.state = spl_token_2022::state::AccountState::Initialized.into(); + } + ExtensionType::InterestBearingConfig => { + let extension = mint + .init_extension::(true) + .expect("Failed to init InterestBearingConfig"); + extension.rate_authority = Default::default(); + extension.initialization_timestamp = 0i64.into(); + extension.pre_update_average_rate = 0i16.into(); + extension.last_update_timestamp = 0i64.into(); + extension.current_rate = 0i16.into(); + } + ExtensionType::MetadataPointer => { + let extension = mint + .init_extension::(true) + .expect("Failed to init MetadataPointer"); + extension.authority = Default::default(); + extension.metadata_address = Default::default(); + } + ExtensionType::GroupPointer => { + let extension = mint + .init_extension::(true) + .expect("Failed to init GroupPointer"); + extension.authority = Default::default(); + extension.group_address = Default::default(); + } + ExtensionType::GroupMemberPointer => { + if let Ok(extension) = mint.init_extension::(true) { + extension.authority = Some(solana_pubkey::Pubkey::new_unique()).try_into().unwrap(); + extension.member_address = Some(solana_pubkey::Pubkey::new_unique()).try_into().unwrap(); + } else { + panic!("Failed to init GroupMemberPointer"); + } + } + ExtensionType::MintCloseAuthority => { + let extension = mint + .init_extension::(true) + .expect("Failed to init MintCloseAuthority"); + extension.close_authority = Default::default(); + } + ExtensionType::PermanentDelegate => { + let extension = mint + .init_extension::(true) + .expect("Failed to init PermanentDelegate"); + extension.delegate = Default::default(); + } + ExtensionType::ScaledUiAmount => { + let extension = mint + .init_extension::(true) + .expect("Failed to init ScaledUiAmount"); + *extension = Default::default(); + extension.multiplier = spl_token_2022::extension::scaled_ui_amount::PodF64::from(1.0); + extension.new_multiplier = spl_token_2022::extension::scaled_ui_amount::PodF64::from(1.0); + } + ExtensionType::TokenMetadata => { + mint.init_variable_len_extension(&TokenMetadata { + update_authority: Default::default(), + mint: solana_pubkey::Pubkey::new_unique(), + name: String::from("Test"), + symbol: String::from("TEST"), + uri: String::from("https://example.com/token.json"), + additional_metadata: vec![], + }, false).expect("Failed to init TokenMetadata"); + } + ExtensionType::ConfidentialTransferMint => { + let extension = mint + .init_extension::(true) + .expect("Failed to init ConfidentialTransferMint"); + extension.authority = Default::default(); + extension.auto_approve_new_accounts = false.into(); + extension.auditor_elgamal_pubkey = Default::default(); + } + ExtensionType::ConfidentialTransferFeeConfig => { + let extension = mint + .init_extension::(true) + .expect("Failed to init ConfidentialTransferFeeConfig"); + extension.authority = Default::default(); + extension.withdraw_withheld_authority_elgamal_pubkey = Default::default(); + extension.harvest_to_mint_enabled = false.into(); + extension.withheld_amount = Default::default(); + } + ExtensionType::TokenGroup => { + if let Ok(extension) = mint.init_extension::(true) { + *extension = TokenGroup { + update_authority: Default::default(), + mint: solana_pubkey::Pubkey::new_unique(), + size: 0u64.into(), + max_size: 100u64.into(), + }; + } else { + panic!("Failed to init TokenGroup"); + } + } + ExtensionType::TokenGroupMember => { + if let Ok(extension) = mint.init_extension::(true) { + *extension = TokenGroupMember { + mint: solana_pubkey::Pubkey::new_unique(), + group: solana_pubkey::Pubkey::new_unique(), + member_number: 0u64.into(), + }; + } else { + panic!("Failed to init TokenGroupMember"); + } + } + _ => {} + } + } + + data + } + + /// Calculate expected ATA account size using token-2022 method + /// Adds `ImmutableOwner` as it is always included in ATA accounts + pub fn calculate_expected_ata_data_size(mint_extensions: &[ExtensionType]) -> usize { + let mut account_extensions = + ExtensionType::get_required_init_account_extensions(mint_extensions); + + // ATA always includes ImmutableOwner, so include it in our comparison + if !account_extensions.contains(&ExtensionType::ImmutableOwner) { + account_extensions.push(ExtensionType::ImmutableOwner); + } + + ExtensionType::try_calculate_account_len::( + &account_extensions, + ) + .expect("Failed to calculate account length") + } + + const MINT_PAD_SIZE: usize = 83; + + /// Create a basic mint with no extensions for testing + fn create_base_mint_data() -> Vec { + let mut data = vec![0u8; MINT_BASE_SIZE + MINT_PAD_SIZE + 5]; + + data[0..4].copy_from_slice(&1u32.to_le_bytes()); + data[MINT_BASE_SIZE + MINT_PAD_SIZE] = 1; + + data + } + + #[test] + fn test_no_extensions() { + let mint_data = create_base_mint_data(); + let expected_size = calculate_expected_ata_data_size(&[]); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!( + result, + Some(expected_size), + "No extensions should return base account size" + ); + } + + #[test] + fn test_single_extensions() { + let extensions_to_test = vec![ + ( + ExtensionType::TransferFeeConfig, + "TransferFeeConfig should add TransferFeeAmount extension to account size", + ), + ( + ExtensionType::TransferHook, + "TransferHook should add TransferHookAccount extension to account size", + ), + ( + ExtensionType::Pausable, + "PausableConfig should add PausableAccount extension to account size", + ), + ( + ExtensionType::NonTransferable, + "NonTransferable should be supported", + ), + ]; + + for (extension, description) in extensions_to_test { + let extensions = vec![extension]; + let mint_data = create_mint_data_with_extensions(&extensions); + let expected_size = calculate_expected_ata_data_size(&extensions); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!(result, Some(expected_size), "{}", description); + } + } + + #[test] + fn test_extensions_without_account_data() { + let extensions = vec![ + ExtensionType::DefaultAccountState, + ExtensionType::InterestBearingConfig, + ExtensionType::MintCloseAuthority, + ExtensionType::PermanentDelegate, + ExtensionType::MetadataPointer, + ExtensionType::GroupPointer, + ]; + + for extension in extensions { + let mint_data = create_mint_data_with_extensions(&vec![extension]); + let expected_size = calculate_expected_ata_data_size(&vec![extension]); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!( + result, + Some(expected_size), + "Extension {:?} should match official calculation", + extension + ); + + let base_size_with_immutable_owner = calculate_expected_ata_data_size(&[]); + assert_eq!( + expected_size, base_size_with_immutable_owner, + "Extension {:?} should not add to account size", + extension + ); + } + } + + #[test] + fn test_multiple_extensions_with_account_data() { + let extensions = vec![ + ExtensionType::TransferFeeConfig, + ExtensionType::TransferHook, + ExtensionType::Pausable, + ]; + + let mint_data = create_mint_data_with_extensions(&extensions); + let expected_size = calculate_expected_ata_data_size(&extensions); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!( + result, + Some(expected_size), + "Multiple extensions should correctly sum account sizes" + ); + } + + #[test] + fn test_mixed_extensions() { + let extensions = vec![ + ExtensionType::TransferFeeConfig, + ExtensionType::DefaultAccountState, + ExtensionType::TransferHook, + ExtensionType::InterestBearingConfig, + ExtensionType::MetadataPointer, + ]; + + let mint_data = create_mint_data_with_extensions(&extensions); + let expected_size = calculate_expected_ata_data_size(&extensions); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!( + result, + Some(expected_size), + "Mixed extensions should correctly calculate only account-side sizes" + ); + } + + fn create_mint_with_unsupported_extension(extension_type: u16) -> Vec { + let mut mint_data = create_base_mint_data(); + mint_data.resize(170, 0); + mint_data[165] = 1; // AccountType::Mint + mint_data[166..168].copy_from_slice(&extension_type.to_le_bytes()); + mint_data[168..170].copy_from_slice(&[0u8, 0u8]); + mint_data + } + + #[test] + fn test_unsupported_extensions_return_none() { + // These extensions should cause our function to return None (fall back to CPI) + let unsupported_extensions = vec![ + 29, // token-2022 extensions end at 27, plus we support the upcoming 28 + 30, 420, + ]; + + for &extension_type in &unsupported_extensions { + let mint_data = create_mint_with_unsupported_extension(extension_type); + let result = calculate_account_size_from_mint_extensions(&mint_data); + assert_eq!( + result, None, + "Unsupported extension {:?} should return None", + extension_type + ); + } + } + + #[test] + fn test_empty_extension_data() { + let mut mint_data = create_base_mint_data(); + mint_data.extend_from_slice(&[0u8, 0u8, 0u8, 0u8]); + + let result = calculate_account_size_from_mint_extensions(&mint_data); + let expected_size = calculate_expected_ata_data_size(&[]); + assert_eq!( + result, + Some(expected_size), + "Empty extension data should return base size" + ); + } + + fn create_mint_with_mock_token_metadata() -> Vec { + let mut mint_data = std::vec![0u8; 82 + 32]; // Base mint (82) + some extension space + + // Set up basic mint structure + mint_data[0..4].copy_from_slice(&[0, 0, 0, 0]); // mint_authority (None) + mint_data[4..12].copy_from_slice(&[0; 8]); // supply + mint_data[12] = 6; // decimals + mint_data[13] = 1; // is_initialized = true + mint_data[14..18].copy_from_slice(&[0, 0, 0, 0]); // freeze_authority (None) + + // Add account type at the end (for extensions) + let account_type_offset = 82; + mint_data[account_type_offset] = 1; // AccountType::Mint + + // Add a mock TokenMetadata TLV entry + let tlv_offset = account_type_offset + 1; + mint_data[tlv_offset..tlv_offset + 2].copy_from_slice(&[19u8, 0]); // Type: TokenMetadata (19) + mint_data[tlv_offset + 2..tlv_offset + 4].copy_from_slice(&[20u8, 0]); // Length: 20 bytes + // Mock 20 bytes of metadata content + mint_data[tlv_offset + 4..tlv_offset + 24].copy_from_slice(&[1u8; 20]); + mint_data + } + + #[test] + fn test_token_metadata_variable_length() { + // Create a simple mint data with manually constructed TokenMetadata TLV + let mint_data = create_mint_with_mock_token_metadata(); + + // Test our inline parser + let inline_size = calculate_account_size_from_mint_extensions(&mint_data); + + // TokenMetadata is mint-only, so account size should be base + ImmutableOwner + let expected_account_size = + calculate_expected_ata_data_size(&[ExtensionType::ImmutableOwner]); + + assert_eq!( + inline_size, + Some(expected_account_size), + "TokenMetadata should be supported inline as a mint-only extension" + ); + } + + #[test] + fn test_systematic_extension_verification() { + let supported_extensions = vec![ + ExtensionType::TransferFeeConfig, + ExtensionType::NonTransferable, + ExtensionType::TransferHook, + ExtensionType::Pausable, + ExtensionType::DefaultAccountState, + ExtensionType::InterestBearingConfig, + ExtensionType::MetadataPointer, + ExtensionType::GroupPointer, + ExtensionType::GroupMemberPointer, + ExtensionType::MintCloseAuthority, + ExtensionType::TransferFeeAmount, + ExtensionType::ImmutableOwner, + ]; + + for extension in &supported_extensions { + match extension { + ExtensionType::TransferFeeAmount | ExtensionType::ImmutableOwner => continue, + _ => {} + } + + let extensions = vec![*extension]; + let mint_data = create_mint_data_with_extensions(&extensions); + let result = calculate_account_size_from_mint_extensions(&mint_data); + + match extension { + ExtensionType::TransferFeeConfig + | ExtensionType::NonTransferable + | ExtensionType::TransferHook + | ExtensionType::Pausable + | ExtensionType::DefaultAccountState + | ExtensionType::InterestBearingConfig + | ExtensionType::MetadataPointer + | ExtensionType::GroupPointer + | ExtensionType::GroupMemberPointer + | ExtensionType::MintCloseAuthority => { + let expected_size = calculate_expected_ata_data_size(&extensions); + assert_eq!( + result, + Some(expected_size), + "Extension {:?} should be supported but calculation differs. Expected: {}, Got: {:?}", + extension, + expected_size, + result + ); + } + _ => {} + } + } + } + + #[test] + fn test_zero_extensions_returns_base_size() { + // Test that mint with no extensions returns base token account size + ImmutableOwner + let mint_data = create_base_mint_data(); + let result = calculate_account_size_from_mint_extensions(&mint_data); + let expected_size = calculate_expected_ata_data_size(&[]); + + assert_eq!( + result, + Some(expected_size), + "Mint with no extensions should return base account size + ImmutableOwner for Token-2022" + ); + } + + #[test] + fn test_token_metadata_account_size_with_max_lengths() { + // Test TokenMetadata extension with maximum field lengths + // Since TokenMetadata is mint-only, account should still get base size + ImmutableOwner + let mint_data = create_mint_with_mock_token_metadata(); + let result = calculate_account_size_from_mint_extensions(&mint_data); + + // TokenMetadata doesn't affect account size directly, but ImmutableOwner is added + let expected_size = calculate_expected_ata_data_size(&[ExtensionType::ImmutableOwner]); + + assert_eq!( + result, + Some(expected_size), + "TokenMetadata with max lengths should not increase account size beyond ImmutableOwner" + ); + } +} diff --git a/p-ata/tests/README.md b/p-ata/tests/README.md new file mode 100644 index 00000000..2eebc321 --- /dev/null +++ b/p-ata/tests/README.md @@ -0,0 +1 @@ +p-ata specific tests are located here; p-ata also runs against the SPL ATA tests in /program/tests. \ No newline at end of file diff --git a/p-ata/tests/bump/mod.rs b/p-ata/tests/bump/mod.rs new file mode 100644 index 00000000..433831ee --- /dev/null +++ b/p-ata/tests/bump/mod.rs @@ -0,0 +1,5 @@ +#![cfg(test)] + +pub mod test_bump_utils; +pub mod test_idemp_oncurve_attack; +pub mod test_mollusk_non_canonical_bump; diff --git a/p-ata/tests/bump/test_bump_utils.rs b/p-ata/tests/bump/test_bump_utils.rs new file mode 100644 index 00000000..0a9139d5 --- /dev/null +++ b/p-ata/tests/bump/test_bump_utils.rs @@ -0,0 +1,88 @@ +#![cfg_attr(feature = "std", allow(dead_code, unused_imports))] + +use ata_mollusk_harness::{ + processor::is_off_curve, test_helpers::address_gen::derive_address_with_bump, +}; +#[cfg(any(test, feature = "std"))] +use { + mollusk_svm::Mollusk, pinocchio::pubkey::Pubkey, + pinocchio_ata_program::test_utils::setup_mollusk_with_programs, + solana_pubkey::Pubkey as SolanaPubkey, +}; + +/// Find a wallet where find_program_address returns the target canonical bump, +/// meaning all bumps > canonical_bump are on-curve. +/// Then derive an on-curve address at canonical_bump + 1. +/// Returns: (wallet, canonical_address, on_curve_address, attack_bump) +pub fn find_wallet_with_on_curve_attack_opportunity( + target_canonical_bump: u8, + token_program: &Pubkey, + mint: &Pubkey, + ata_program_id: &Pubkey, +) -> Option<(Pubkey, Pubkey, Pubkey, u8)> { + const MAX_FIND_ATTEMPTS: u32 = 100_000; + let attack_bump = target_canonical_bump + 1; + + for _ in 0..MAX_FIND_ATTEMPTS { + let wallet = SolanaPubkey::new_unique(); + + let (canonical_addr, found_bump) = SolanaPubkey::find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + &SolanaPubkey::new_from_array(*ata_program_id), + ); + + // We need find_program_address to return exactly the target canonical bump + // This means attack_bump and all higher bumps are on-curve + if found_bump != target_canonical_bump { + continue; + } + + // Manually derive the attack address using the higher bump + let seeds: &[&[u8]; 3] = &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()]; + let attack_addr = derive_address_with_bump( + seeds, + attack_bump, + &SolanaPubkey::new_from_array(*ata_program_id), + ); + + return Some(( + wallet.to_bytes(), + canonical_addr.to_bytes(), + attack_addr.to_bytes(), + attack_bump, + )); + } + None +} + +/// Setup mollusk with both ATA and token programs for bump testing +#[cfg(any(test, feature = "std"))] +pub fn setup_mollusk_for_bump_tests(token_program_id: &Pubkey) -> Mollusk { + setup_mollusk_with_programs(&SolanaPubkey::new_from_array(*token_program_id)) +} + +#[cfg(any(test, feature = "std"))] +mod tests { + use super::*; + + #[test] + fn test_derive_address_with_bump() { + use std::eprintln; + let wallet = SolanaPubkey::new_unique(); + let token_program = spl_token::id(); + let mint = SolanaPubkey::new_unique(); + let ata_program_id = spl_associated_token_account::id(); + + // Test that our manual derivation matches find_program_address + let (expected_addr, expected_bump) = SolanaPubkey::find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + &ata_program_id, + ); + eprintln!("expected_addr: {:?}", expected_addr); + eprintln!("expected_bump: {:?}", expected_bump); + let seeds: &[&[u8]; 3] = &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()]; + let derived_addr = derive_address_with_bump(seeds, expected_bump, &ata_program_id); + eprintln!("derived_addr: {:?}", derived_addr); + assert_eq!(expected_addr, derived_addr); + } +} diff --git a/p-ata/tests/bump/test_idemp_oncurve_attack.rs b/p-ata/tests/bump/test_idemp_oncurve_attack.rs new file mode 100644 index 00000000..0d70baf0 --- /dev/null +++ b/p-ata/tests/bump/test_idemp_oncurve_attack.rs @@ -0,0 +1,127 @@ +use { + super::test_bump_utils::{ + find_wallet_with_on_curve_attack_opportunity, setup_mollusk_for_bump_tests, + }, + mollusk_svm::{program::loader_keys::LOADER_V3, result::Check}, + ata_mollusk_harness::{ + account_builder::AccountBuilder, build_create_ata_instruction, CreateAtaInstructionType, + NATIVE_LOADER_ID, + }, + solana_pubkey::Pubkey, + solana_sdk::{ + account::Account, program_error::ProgramError, signature::Keypair, signer::Signer, + }, + solana_sdk_ids::{system_program, sysvar}, + std::vec::Vec, +}; + +/// Simulate an attacker manually creating an account outside of the ATA program. +fn create_manual_token_account(mint: Pubkey, owner: Pubkey, token_program: Pubkey) -> Account { + let token_account_data = AccountBuilder::token_account(&mint, &owner, 0, &spl_token::id()).data; + + Account { + lamports: 2_039_280, + data: token_account_data, + owner: token_program, + executable: false, + rent_epoch: 0, + } +} + +#[test] +fn test_rejects_on_curve_address_in_idempotent_check() { + let ata_program_id = spl_associated_token_account::id(); + let token_program_id = spl_token::id(); + let mint_pubkey = Pubkey::new_unique(); + let payer = Keypair::new(); + + // Find a wallet where find_program_address returns bump 253 + // This means bump 254 and 255 are both on curve + let first_off_curve_bump = 253u8; + + let (wallet, _, on_curve_attack_address, attack_bump) = + find_wallet_with_on_curve_attack_opportunity( + first_off_curve_bump, + &token_program_id.to_bytes(), + &mint_pubkey.to_bytes(), + &ata_program_id.to_bytes(), + ) + .expect("Could not find wallet with canonical bump 253 and on-curve attack opportunity"); + + let mollusk = setup_mollusk_for_bump_tests(&token_program_id.to_bytes()); + + // Step 1: Manually create a token account at the on-curve address + // This simulates the attack where someone creates an account at an on-curve (invalid PDA) address + let manual_token_account = create_manual_token_account( + mint_pubkey, + Pubkey::new_from_array(wallet), + token_program_id, + ); + + let accounts = vec![ + ( + payer.pubkey(), + Account::new(1_000_000_000, 0, &system_program::id()), + ), + ( + Pubkey::new_from_array(on_curve_attack_address), + manual_token_account, + ), // Pre-existing account at on-curve address + ( + Pubkey::new_from_array(wallet), + Account::new(0, 0, &system_program::id()), + ), + ( + mint_pubkey, + Account { + lamports: 1_461_600, + data: AccountBuilder::mint(6, &spl_token::id()).data, + owner: token_program_id, + executable: false, + rent_epoch: 0, + }, + ), + ( + system_program::id(), + Account { + lamports: 0, + data: Vec::new(), + owner: NATIVE_LOADER_ID, + executable: true, + rent_epoch: 0, + }, + ), + ( + token_program_id, + Account { + lamports: 0, + data: Vec::new(), + owner: LOADER_V3, + executable: true, + rent_epoch: 0, + }, + ), + (sysvar::rent::id(), Account::new(1009200, 17, &sysvar::id())), + ]; + + // Step 2: Try to validate the account with CreateIdempotent using the on-curve address + let idempotent_instruction = build_create_ata_instruction( + ata_program_id, + payer.pubkey(), + Pubkey::new_from_array(on_curve_attack_address), + Pubkey::new_from_array(wallet), + mint_pubkey, + token_program_id, + CreateAtaInstructionType::CreateIdempotent { + bump: Some(attack_bump), + }, + ); + + // This should fail with InvalidSeeds because the address is on-curve (invalid PDA) + // The is_off_curve check in check_idempotent_account prevents this attack + mollusk.process_and_validate_instruction( + &idempotent_instruction, + &accounts, + &[Check::err(ProgramError::InvalidSeeds)], + ); +} diff --git a/p-ata/tests/bump/test_mollusk_non_canonical_bump.rs b/p-ata/tests/bump/test_mollusk_non_canonical_bump.rs new file mode 100644 index 00000000..b89d914d --- /dev/null +++ b/p-ata/tests/bump/test_mollusk_non_canonical_bump.rs @@ -0,0 +1,136 @@ +use { + super::test_bump_utils::setup_mollusk_for_bump_tests, + mollusk_svm::result::Check, + ata_mollusk_harness::{ + build_create_ata_instruction, create_ata_test_accounts, CreateAtaInstructionType, + }, + solana_pubkey::Pubkey, + solana_sdk::{program_error::ProgramError, signature::Keypair, signer::Signer}, + std::vec::Vec, +}; + +/// Find a wallet such that its canonical off-curve bump equals `target_canonical` and also +/// has at least one lower off-curve bump. Returns: +/// (wallet, canonical_addr, sub_addr) +fn find_wallet_pair( + canonical_bump: u8, + sub_bump: u8, + token_program: &Pubkey, + mint: &Pubkey, + ata_program_id: &Pubkey, +) -> (Pubkey, Pubkey, Pubkey) { + assert!(canonical_bump > sub_bump); + const MAX_FIND_ATTEMPTS: u32 = 40_000; + for _ in 0..MAX_FIND_ATTEMPTS { + let wallet = Pubkey::new_unique(); + + let (canonical_addr, bump) = Pubkey::find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + ata_program_id, + ); + + if bump != canonical_bump { + continue; + } + + if let Ok(sub_addr) = Pubkey::create_program_address( + &[ + wallet.as_ref(), + token_program.as_ref(), + mint.as_ref(), + &[sub_bump], + ], + ata_program_id, + ) { + return (wallet, canonical_addr, sub_addr); + } + } + panic!( + "Failed to find wallet for canonical {} / sub {} after {} attempts", + canonical_bump, sub_bump, MAX_FIND_ATTEMPTS + ); +} + +#[test] +fn test_rejects_suboptimal_bump() { + let ata_program_id = spl_associated_token_account::id(); + let token_program_id = spl_token::id(); + let mint_pubkey = Pubkey::new_unique(); + let payer = Keypair::new(); + + // Define (canonical, sub) bump pairs to verify. + let pairs = [ + (255u8, 254u8), + (254u8, 253u8), + (255u8, 252u8), + (254u8, 252u8), + (255u8, 250u8), + (254u8, 250u8), + ]; + + let mollusk = setup_mollusk_for_bump_tests(&token_program_id.to_bytes()); + + let mut wallet_infos = Vec::new(); + for &(canonical, sub) in &pairs { + let (wallet, canonical_addr, sub_addr) = find_wallet_pair( + canonical, + sub, + &token_program_id, + &mint_pubkey, + &ata_program_id, + ); + wallet_infos.push((wallet, canonical, canonical_addr, sub, sub_addr)); + } + + for (wallet, canonical_bump, canonical_addr, sub_bump, sub_addr) in wallet_infos { + // Test 1: Sub-optimal should fail + { + let ix_fail = build_create_ata_instruction( + ata_program_id, + payer.pubkey(), + sub_addr, + wallet, + mint_pubkey, + token_program_id, + CreateAtaInstructionType::Create { + bump: Some(sub_bump), + account_len: None, + }, + ); + + let accounts = + create_ata_test_accounts(&payer, sub_addr, wallet, mint_pubkey, token_program_id); + + mollusk.process_and_validate_instruction( + &ix_fail, + &accounts, + &[Check::err(ProgramError::InvalidInstructionData)], + ); + } + + { + let ix_ok = build_create_ata_instruction( + ata_program_id, + payer.pubkey(), + canonical_addr, + wallet, + mint_pubkey, + token_program_id, + CreateAtaInstructionType::Create { + bump: Some(canonical_bump), + account_len: None, + }, + ); + + let accounts = create_ata_test_accounts( + &payer, + canonical_addr, + wallet, + mint_pubkey, + token_program_id, + ); + + mollusk.process_and_validate_instruction(&ix_ok, &accounts, &[Check::success()]); + } + } +} diff --git a/p-ata/tests/mod.rs b/p-ata/tests/mod.rs new file mode 100644 index 00000000..94841884 --- /dev/null +++ b/p-ata/tests/mod.rs @@ -0,0 +1,4 @@ +#![cfg(test)] + +pub mod bump; +pub mod token_account_len; diff --git a/p-ata/tests/token_account_len/mod.rs b/p-ata/tests/token_account_len/mod.rs new file mode 100644 index 00000000..ab538969 --- /dev/null +++ b/p-ata/tests/token_account_len/mod.rs @@ -0,0 +1,3 @@ +#![cfg(test)] + +mod test_account_length_limits; diff --git a/p-ata/tests/token_account_len/test_account_length_limits.rs b/p-ata/tests/token_account_len/test_account_length_limits.rs new file mode 100644 index 00000000..098add25 --- /dev/null +++ b/p-ata/tests/token_account_len/test_account_length_limits.rs @@ -0,0 +1,114 @@ +use { + mollusk_svm::result::Check, + ata_mollusk_harness::{ + build_create_ata_instruction, create_ata_test_accounts, setup_mollusk_with_programs, + CreateAtaInstructionType, + }, + solana_pubkey::Pubkey, + solana_sdk::{program_error::ProgramError, signature::Keypair, signer::Signer}, + std::vec, +}; + +use pinocchio_ata_program::entrypoint::MAX_SANE_ACCOUNT_LENGTH; + +#[test] +fn test_account_length_too_small_cases() { + let test_cases = vec![ + (0, "zero length"), + (1, "single byte"), + (10, "very small"), + (164, "just under SPL Token minimum"), + (165, "SPL Token minimum but insufficient for Token-2022"), + (169, "just under Token-2022 minimum"), + ]; + + let mollusk = setup_mollusk_with_programs(&spl_token_2022::id()); + let program_id = spl_associated_token_account::id(); + + let wallet = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let token_program = spl_token_2022::id(); + let payer = Keypair::new(); + let (ata_address, bump) = Pubkey::find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + &program_id, + ); + + for (length, _) in &test_cases { + let instruction = build_create_ata_instruction( + program_id, + payer.pubkey(), + ata_address, + wallet, + mint, + token_program, + CreateAtaInstructionType::Create { + bump: Some(bump), + account_len: Some(*length), + }, + ); + + let accounts = create_ata_test_accounts(&payer, ata_address, wallet, mint, token_program); + + // Token-2022 requires minimum 170 bytes (165 base + 5 for ImmutableOwner) + // All lengths under 170 should fail with InvalidAccountData + mollusk.process_and_validate_instruction( + &instruction, + &accounts, + &[Check::err(ProgramError::InvalidAccountData)], + ); + } +} + +#[test] +fn test_account_length_boundary_values() { + let test_cases = vec![ + (170, "standard extended token account"), + (512, "small extension"), + (1024, "medium extension"), + (MAX_SANE_ACCOUNT_LENGTH - 1, "just under limit"), + (MAX_SANE_ACCOUNT_LENGTH, "at limit"), + (MAX_SANE_ACCOUNT_LENGTH + 1, "just over limit"), + (4096, "way over limit"), + (65535, "max over limit"), + ]; + + let mollusk = setup_mollusk_with_programs(&spl_token_2022::id()); + let program_id = spl_associated_token_account::id(); + + let wallet = Pubkey::new_unique(); + let mint = Pubkey::new_unique(); + let token_program = spl_token_2022::id(); + let payer = Keypair::new(); + let (ata_address, bump) = Pubkey::find_program_address( + &[wallet.as_ref(), token_program.as_ref(), mint.as_ref()], + &program_id, + ); + + for (length, _) in test_cases { + let instruction = build_create_ata_instruction( + program_id, + payer.pubkey(), + ata_address, + wallet, + mint, + token_program, + CreateAtaInstructionType::Create { + bump: Some(bump), + account_len: Some(length), + }, + ); + + let accounts = create_ata_test_accounts(&payer, ata_address, wallet, mint, token_program); + + if length <= MAX_SANE_ACCOUNT_LENGTH { + mollusk.process_and_validate_instruction(&instruction, &accounts, &[Check::success()]); + } else { + mollusk.process_and_validate_instruction( + &instruction, + &accounts, + &[Check::err(ProgramError::InvalidInstructionData)], + ); + } + } +}