diff --git a/Cargo.lock b/Cargo.lock index df9d5c3f..dd0dad2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,23 +63,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "affinity" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763e484feceb7dd021b21c5c6f81aee06b1594a743455ec7efbf72e6355e447b" -dependencies = [ - "cfg-if 1.0.0", - "errno", - "libc", - "num_cpus", -] - [[package]] name = "agave-banking-stage-ingress-types" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c1fb85c09da8aebdb52e9ecb6e66d359a02efacd4b40c6cd79f50039327bf4e" +checksum = "48510c443c793379c02e3ce757755c9abfb2010ce23f9091b62e601230418de6" dependencies = [ "crossbeam-channel", "solana-perf", @@ -87,9 +75,9 @@ dependencies = [ [[package]] name = "agave-geyser-plugin-interface" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df63ffb691b27f0253e893d083126cbe98a6b1ace29108992310f323f1ac50b0" +checksum = "8cf87abcb4637e982cb7995b9dd53485e8c7a823c8963319cb651e47aca9cf26" dependencies = [ "log", "solana-clock", @@ -99,30 +87,11 @@ dependencies = [ "thiserror 2.0.12", ] -[[package]] -name = "agave-thread-manager" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc27cbfbda0a3c19799936ad20b802db086c20105323d1d8885da4e7d5bf4ec" -dependencies = [ - "affinity", - "anyhow", - "cfg-if 1.0.0", - "log", - "num_cpus", - "rayon", - "serde", - "solana-metrics", - "thread-priority", - "tokio", - "toml 0.8.20", -] - [[package]] name = "agave-transaction-view" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba2aec0682aa448f93db9b93df8fb331c119cb4d66fe9ba61d6b42dd3a91105" +checksum = "f6249a9fb672efff152c578ee561597b52a8eaab9cc6fe7c3ad7ba44359f83ae" dependencies = [ "solana-hash", "solana-message", @@ -3036,9 +3005,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" @@ -3902,7 +3871,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml 0.5.11", + "toml", ] [[package]] @@ -4799,15 +4768,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5080,9 +5040,9 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c472eebf9ec7ee72c8d25e990a2eaf6b0b783619ef84d7954c408d6442ad5e57" +checksum = "e3a8e4aacc7c681419ae63c1de36349d2156d5a4f4ffaea8e507335013e57189" dependencies = [ "Inflector", "base64 0.22.1", @@ -5119,9 +5079,9 @@ dependencies = [ [[package]] name = "solana-account-decoder-client-types" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3485b583fcc58b5fa121fa0b4acb90061671fb1a9769493e8b4ad586581f47" +checksum = "6329c4f360f5173dd6f65022708486cdd24d302841058e2310945a2502284105" dependencies = [ "base64 0.22.1", "bs58", @@ -5148,9 +5108,9 @@ dependencies = [ [[package]] name = "solana-accounts-db" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65a1a23a53cae19cb92bab2cbdd9e289e5210bb12175ce27642c94adf74b220" +checksum = "5bebb1bbe676467db67aa8f05f86ef681be958e1f4e87dc949ec2996b588729d" dependencies = [ "ahash 0.8.11", "bincode", @@ -5214,9 +5174,9 @@ dependencies = [ [[package]] name = "solana-address-lookup-table-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c758a82a60e5fcc93b3ee00615b0e244295aa8b2308475ea2b48f4900862a2e0" +checksum = "b87ae97f2d1b91a9790c1e35dba3f90a4d595d105097ad93fa685cbc034ad0f1" dependencies = [ "bincode", "bytemuck", @@ -5248,9 +5208,9 @@ dependencies = [ [[package]] name = "solana-banks-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420dc40674f4a4df1527277033554b1a1b84a47e780cdb7dad151426f5292e55" +checksum = "71e8b93a73f583fb03c9a43be9185c2e04c8a5df84e3c20fd813f0ff79a12142" dependencies = [ "borsh 1.5.5", "futures 0.3.31", @@ -5265,9 +5225,9 @@ dependencies = [ [[package]] name = "solana-banks-interface" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f8a6b6dc15262f14df6da7332e7dc7eb5fa04c86bf4dfe69385b71c2860d19" +checksum = "e54bdc2f951d900289a3de58f8fc835fcea67fdaaea390b447e16a8a403a2399" dependencies = [ "serde", "serde_derive", @@ -5277,9 +5237,9 @@ dependencies = [ [[package]] name = "solana-banks-server" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea32797f631ff60b3eb3c793b0fddd104f5ffdf534bf6efcc59fbe30cd23b15" +checksum = "d31f902ad3ea81a92fb48619e5d852ce7500f1aecb5adc52621ae4856cc53ef0" dependencies = [ "bincode", "crossbeam-channel", @@ -5333,9 +5293,9 @@ dependencies = [ [[package]] name = "solana-bloom" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf4babf9225c318efa34d7017eb3b881ed530732ad4dc59dfbde07f6144f27a" +checksum = "fe9e9b78abe57874ed1c315156567d37d0de6ef3cd21baf546833ebdc2eeda15" dependencies = [ "bv", "fnv", @@ -5374,9 +5334,9 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cbc2581d0f39cd7698e46baa06fc5e8928b323a85ed3a4fdbdfe0d7ea9fc152" +checksum = "6931e8893b48e3a1c8124938f580fff857d84895582578cc7dbf100dd08d2c8f" dependencies = [ "bincode", "libsecp256k1", @@ -5391,7 +5351,7 @@ dependencies = [ "solana-clock", "solana-compute-budget", "solana-cpi", - "solana-curve25519", + "solana-curve25519 2.2.4", "solana-feature-set", "solana-hash", "solana-instruction", @@ -5423,9 +5383,9 @@ dependencies = [ [[package]] name = "solana-bucket-map" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12484b98db9e154d8189a7f632fe0766440abe4e58c5426f47157ece5b8730f3" +checksum = "c11df4362edfa9e3157e37cdba2f10cafe23c550aa4038f3c3b302573937af9d" dependencies = [ "bv", "bytemuck", @@ -5443,9 +5403,9 @@ dependencies = [ [[package]] name = "solana-builtins" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab1c09b653992c685c56c611004a1c96e80e76b31a2a2ecc06c47690646b98a" +checksum = "b9240641f944ece59e097c9981bdc33b2f519cbd91b9764ff5f62c307d986a3d" dependencies = [ "solana-address-lookup-table-program", "solana-bpf-loader-program", @@ -5465,9 +5425,9 @@ dependencies = [ [[package]] name = "solana-builtins-default-costs" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ee734c35b736e632aa3b1367f933d93ee7b4129dd1e20ca942205d4834054e" +checksum = "1fb6728141dc45bdde9d68b67bb914013be28f94a2aea8bb7131ea8c6161c30e" dependencies = [ "ahash 0.8.11", "lazy_static", @@ -5488,9 +5448,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9ef7be5c7a6fde4ae6864279a98d48a9454f70b0d3026bc37329e7f632fba6" +checksum = "3c3c8414401ef96e9276e8c74238628a6faa531185ddc11f6a7bd644cdb8782e" dependencies = [ "chrono", "clap 2.34.0", @@ -5505,7 +5465,7 @@ dependencies = [ "solana-native-token", "solana-presigner", "solana-pubkey", - "solana-remote-wallet", + "solana-remote-wallet 2.2.4", "solana-seed-phrase", "solana-signature", "solana-signer", @@ -5517,9 +5477,8 @@ dependencies = [ [[package]] name = "solana-clap-v3-utils" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e0d663063c8949b0f71b96b5116acd46322072c8be5d1f0e385e72a3941fb" +version = "2.3.0" +source = "git+https://github.com/anza-xyz/agave?rev=8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86#8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" dependencies = [ "chrono", "clap 3.2.25", @@ -5534,12 +5493,12 @@ dependencies = [ "solana-native-token", "solana-presigner", "solana-pubkey", - "solana-remote-wallet", + "solana-remote-wallet 2.3.0", "solana-seed-derivable", "solana-seed-phrase", "solana-signature", "solana-signer", - "solana-zk-token-sdk", + "solana-zk-token-sdk 2.3.0", "thiserror 2.0.12", "tiny-bip39", "uriparse", @@ -5548,9 +5507,9 @@ dependencies = [ [[package]] name = "solana-cli-config" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdfa01757b1e6016028ad3bb35eb8efd022aadab0155621aedd71f0c566f03a" +checksum = "6a13234fa9ea96d6cf1dad79dfd9d63f482f1ce0e8decb6f8d13a3686f5c8ec8" dependencies = [ "dirs-next", "lazy_static", @@ -5564,9 +5523,9 @@ dependencies = [ [[package]] name = "solana-cli-output" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07214f677077717053580642e7c7f90d471d03a48874792e5fca876443dff830" +checksum = "bc18bc6310155d40b29853c649c141c1b0658832eeccc7a171e977f6bde514ae" dependencies = [ "Inflector", "base64 0.22.1", @@ -5607,9 +5566,9 @@ dependencies = [ [[package]] name = "solana-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e25b7073890561a6b7875a921572fc4a9a2c78b3e60fb8e0a7ee4911961f8bd" +checksum = "5e827416867d988cbba327b6e448ad0bfb85ba44f080c6a02a00aa498c2249c4" dependencies = [ "async-trait", "bincode", @@ -5708,9 +5667,9 @@ dependencies = [ [[package]] name = "solana-compute-budget" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab40b24943ca51f1214fcf7979807640ea82a8387745f864cf3cd93d1337b01" +checksum = "46e593ce26764fa3366b6d125b9f2455f6cd8d557f86b4f3c7b7c517db6d8f5f" dependencies = [ "solana-fee-structure", "solana-program-entrypoint", @@ -5718,9 +5677,9 @@ dependencies = [ [[package]] name = "solana-compute-budget-instruction" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6ef2a514cde8dce77495aefd23671dc46f638f504765910424436bc745dc04" +checksum = "240e28cf764d1468f2388fb0d10b70278a64d47277ff552379116ba45d609cd1" dependencies = [ "log", "solana-borsh", @@ -5752,9 +5711,9 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba922073c64647fe62f032787d34d50a8152533b5a5c85608ae1b2afb00ab63" +checksum = "bfc6b8ea70ed5123412655ed15e7e0e29f06a7d5b82eb2572bee608d7755afb7" dependencies = [ "qualifier_attr", "solana-program-runtime", @@ -5762,9 +5721,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab5647203179631940e0659a635e5d3f514ba60f6457251f8f8fbf3830e56b0" +checksum = "2417094a8c5c2d60812a5bd6f0bd31bdefc49479826c10347a85d217e088c964" dependencies = [ "bincode", "chrono", @@ -5786,9 +5745,9 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0392439ea05772166cbce3bebf7816bdcc3088967039c7ce050cea66873b1c50" +checksum = "55ad0b507b4044e2690915c9aa69eacfd51b1fa55e4deeca662ee5cff7d7d1f4" dependencies = [ "async-trait", "bincode", @@ -5810,12 +5769,11 @@ dependencies = [ [[package]] name = "solana-core" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6ddd0c2515aa9fcb6107796fe4af5af17b9d1e49eeb8756588a443b7a8ab20" +checksum = "093f348a95455bd38cd23c4cd1baa7c2b3e8f6042ed20cd6e0824d5f6c115688" dependencies = [ "agave-banking-stage-ingress-types", - "agave-thread-manager", "agave-transaction-view", "ahash 0.8.11", "anyhow", @@ -5905,9 +5863,9 @@ dependencies = [ [[package]] name = "solana-cost-model" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a675ead1473b32a7a5735801608b35cbd8d3f5057ca8dbafdd5976146bb7e9e4" +checksum = "d4046449f81662b0b79b3f7a5e88412ae58fd63f8ef4af472a528d522a44500a" dependencies = [ "ahash 0.8.11", "lazy_static", @@ -5948,9 +5906,22 @@ dependencies = [ [[package]] name = "solana-curve25519" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f213e3a853a23814dee39d730cd3a5583b7b1e6b37b2cd4d940bbe62df7acc16" +checksum = "9b3d15f1a893ced38529d44d7fe0d4348dc38c28fea13b6d6be5d13d438a441f" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall", + "subtle", + "thiserror 2.0.12", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.0" +source = "git+https://github.com/anza-xyz/agave?rev=8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86#8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" dependencies = [ "bytemuck", "bytemuck_derive", @@ -6003,9 +5974,9 @@ dependencies = [ [[package]] name = "solana-entry" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17eeec2852ad402887e80aa59506eee7d530d27b8c321f4824f8e2e7fe3e8cb2" +checksum = "d3e99b5e5454f7fb84f58dab0ffac9a4d2264d036eaf88800b9ea4f0ed53fa59" dependencies = [ "bincode", "crossbeam-channel", @@ -6099,9 +6070,9 @@ dependencies = [ [[package]] name = "solana-faucet" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8bd25a809e1763794de4c28d699d859d77947fd7c6b11883c781d2cdfb3cf2" +checksum = "eb756c559691129893c6bdf45624b5ff8302bfb6f1a5ef1d521f4f3bd52806b5" dependencies = [ "bincode", "clap 2.34.0", @@ -6165,9 +6136,9 @@ dependencies = [ [[package]] name = "solana-fee" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee323b500b445d45624ad99a08b12b37c9964ac12debf2cde9ddfad9b06e0073" +checksum = "8c14eaaa9d099e4510c9105522d97778cd66c3d401f0d68eebcf43179a1bf094" dependencies = [ "solana-feature-set", "solana-fee-structure", @@ -6230,9 +6201,9 @@ dependencies = [ [[package]] name = "solana-geyser-plugin-manager" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8287469a6f059411a3940bbc1b0a428b27104827ae1a80e465a1139f8b0773" +checksum = "dcdf5f30f041794ed39070b0a5d29cd62dc858073345309d7a525fa5e4051176" dependencies = [ "agave-geyser-plugin-interface", "bs58", @@ -6261,9 +6232,9 @@ dependencies = [ [[package]] name = "solana-gossip" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "587f7e73d3ee7173f1f66392f1aeb4e582c055ad30f4e40f3a4b2cf9bce434fe" +checksum = "6ff5ce869ea2d5055bca684752237627842f44c0b8471a97035ae6e837b77e12" dependencies = [ "assert_matches", "bincode", @@ -6353,9 +6324,9 @@ dependencies = [ [[package]] name = "solana-inline-spl" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951545bd7d0ab4a878cfc7375ac9f1a475cb6936626677b2ba1d25e7b9f3910b" +checksum = "ed78e6709851bb3fa8a0acb1ee40fbffa888049d042ca132d6ccb8e0b313ac72" dependencies = [ "bytemuck", "solana-pubkey", @@ -6442,9 +6413,9 @@ dependencies = [ [[package]] name = "solana-lattice-hash" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fff3aab7ad7578d0bd2ac32d232015e535dfe268e35d45881ab22db0ba61c1e" +checksum = "780e8609adadf99e09b08a4f45f30fedd82b29ed31a3b3a921bb811ffd1652cc" dependencies = [ "base64 0.22.1", "blake3", @@ -6454,9 +6425,9 @@ dependencies = [ [[package]] name = "solana-ledger" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ef5ef594139afbf9db0dd0468a4d904d3275ce07f3afdb3a9b68d38676a75e" +checksum = "df86148eed1a113592f048fdd943fc64c08adfa413de4818c616bc09c8468101" dependencies = [ "assert_matches", "bincode", @@ -6573,9 +6544,9 @@ dependencies = [ [[package]] name = "solana-loader-v4-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b24999844b09096c79567c1298617efe084860149d875b702ef76e2faa2462" +checksum = "7b0298bf161e18b146230b15e8fa57bd170a05342ab9c1fd996b0241c0f016c2" dependencies = [ "log", "qualifier_attr", @@ -6599,9 +6570,9 @@ dependencies = [ [[package]] name = "solana-log-collector" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa28cd428e0af919d2fafd31c646835622abfd7ed4dba4df68e3c00f461bc66" +checksum = "4d03bf4c676117575be755296e8f21233d74cd28dca227c42e97e86219a27193" dependencies = [ "log", ] @@ -6619,15 +6590,15 @@ dependencies = [ [[package]] name = "solana-measure" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fced2cfeff80f0214af86bc27bc6e798465a45b70329c3b468bb75957c082" +checksum = "0b17ee553110d2bfc454b8784840a4b75867e123d3816e13046989463fed2c6b" [[package]] name = "solana-merkle-tree" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd38db9705b15ff57ddbd9d172c48202dcba078cfc867fe87f01c01d8633fd55" +checksum = "db5394370e4ef6d1b62864cbac88f3bade612115ba3b007cf75c11ab73b6d4b6" dependencies = [ "fast-math", "solana-hash", @@ -6659,9 +6630,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89db46736ae1929db9629d779485052647117f3fcc190755519853b705f6dba5" +checksum = "98b79bd642efa8388791fef7a900bfeb48865669148d523fba041fa7e407312f" dependencies = [ "crossbeam-channel", "gethostname", @@ -6692,9 +6663,9 @@ checksum = "33e9de00960197412e4be3902a6cd35e60817c511137aca6c34c66cd5d4017ec" [[package]] name = "solana-net-utils" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0752a7103c1a5bdbda04aa5abc78281232f2eda286be6edf8e44e27db0cca2a1" +checksum = "ef9db57e121ca1577fb5578d916bed549632be0e54a2098e8325980ac724d283" dependencies = [ "anyhow", "bincode", @@ -6776,9 +6747,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0962d3818fc942a888f7c2d530896aeaf6f2da2187592a67bbdc8cf8a54192" +checksum = "7b87939c18937f8bfad6028779a02fa123b27e986fb2c55fbbf683952a0e4932" dependencies = [ "ahash 0.8.11", "bincode", @@ -6808,9 +6779,9 @@ dependencies = [ [[package]] name = "solana-poh" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3abf53e6af2bc7f3ebd455112a0eb960378882d780e85b62ff3a70b69e02e6" +checksum = "04a72e177ca217b8a711c9b5a227bbaa2678973552e98da3998f0f8eb5bb16de" dependencies = [ "core_affinity", "crossbeam-channel", @@ -6841,9 +6812,9 @@ dependencies = [ [[package]] name = "solana-poseidon" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad1ea160d08dc423c35021fa3e437a5783eb256f5ab8bc3024e27db913acf42" +checksum = "5d2908b48b3828bc04b752d1ff36122f5a06de043258da88df5f8ce64791d208" dependencies = [ "ark-bn254", "light-poseidon", @@ -7024,9 +6995,9 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c3d36fed5548b1a8625eb071df6031a95aa69f884e29bf244821e53c49372bc" +checksum = "ce0a9acc6049c2ae8a2a2dd0b63269ab1a6d8fab4dead1aae75a9bcdd4aa6f05" dependencies = [ "base64 0.22.1", "bincode", @@ -7065,9 +7036,9 @@ dependencies = [ [[package]] name = "solana-program-test" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6caec3df83d39b8da9fd6e80a7847d788b3b869c646fbb8776c3e989e98c0c" +checksum = "b15cedbd823f64af662551bb801687ea98067bbddf06e0394876a40485542667" dependencies = [ "assert_matches", "async-trait", @@ -7129,9 +7100,9 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd251d37c932105a684415db44bee52e75ad818dfecbf963a605289b5aaecc5" +checksum = "52d219147fd3a6753dc4819578fb6830c082a7c26b1559fab0f240fcf11f4e39" dependencies = [ "crossbeam-channel", "futures-util", @@ -7156,9 +7127,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d072e6787b6fa9da86591bcf870823b0d6f87670df3c92628505db7a9131e44" +checksum = "769d66df4ab445ab689ab2c4f10135dfe80576859b4fea1cae7d9bdd7985e4e2" dependencies = [ "async-lock", "async-trait", @@ -7196,9 +7167,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f7b65ddd8ac75efcc31b627d4f161046312994313a4520b65a8b14202ab5d6" +checksum = "7bf3ad7091b26c9bd0ebabff6ac4d825c88ecf2eafdb83de30dffda80ffc2f17" dependencies = [ "lazy_static", "num_cpus", @@ -7206,9 +7177,32 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3c1e6ec719021564b034c550f808778507db54b6a5de99f00799d9ec86168d" +checksum = "4f6c8a74ea5e4c430ca41cae7da03ba7c7c6da0b8c1513aeef16f18b86c5cb30" +dependencies = [ + "console", + "dialoguer", + "hidapi", + "log", + "num-derive", + "num-traits", + "parking_lot 0.12.3", + "qstring", + "semver", + "solana-derivation-path", + "solana-offchain-message", + "solana-pubkey", + "solana-signature", + "solana-signer", + "thiserror 2.0.12", + "uriparse", +] + +[[package]] +name = "solana-remote-wallet" +version = "2.3.0" +source = "git+https://github.com/anza-xyz/agave?rev=8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86#8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" dependencies = [ "console", "dialoguer", @@ -7292,9 +7286,9 @@ dependencies = [ [[package]] name = "solana-rpc" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b978303a9d6f3270ab83fa28ad07a2f4f3181a65ce332b4b5f5d06de5f2a46c5" +checksum = "21e20180ca57beb23d8060ce831ad4f19bb30068da53b21ee9916aa241a144ba" dependencies = [ "base64 0.22.1", "bincode", @@ -7354,9 +7348,9 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb874b757d9d3c646f031132b20d43538309060a32d02b4aebb0f8fc2cd159a" +checksum = "44f1809a424bb8d90aa40990451593cde7e734a060fb52b35e475db585450578" dependencies = [ "async-trait", "base64 0.22.1", @@ -7392,9 +7386,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7105452c4f039fd2c07e6fda811ff23bd270c99f91ac160308f02701eb19043" +checksum = "aa2eb4fe573cd2d59d8672f0d8ac65f64e70c948b36cf97218b9aeb80dca3329" dependencies = [ "anyhow", "base64 0.22.1", @@ -7423,9 +7417,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0244e2bf439ec424179414173cdc8b43e34371608752799c5610bf17430eee18" +checksum = "2712d22c58616762ad8e02fc18556eaf7be4104d5e56b11a2b8aa892c7de2a08" dependencies = [ "solana-account", "solana-commitment-config", @@ -7440,9 +7434,9 @@ dependencies = [ [[package]] name = "solana-runtime" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5335e7925f6dc8d2fdcdc6ead3b190aca65f191a11cef74709a7a6ab5d0d5877" +checksum = "13f58e4566fb3d2e28719ff00646841bb1269fc091fb75ee51da3eb855deef17" dependencies = [ "ahash 0.8.11", "aquamarine", @@ -7526,9 +7520,9 @@ dependencies = [ [[package]] name = "solana-runtime-transaction" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ffec9b80cf744d36696b28ca089bef8058475a79a11b1cee9322a5aab1fa00" +checksum = "8eeea366d9c748124f0e955c7cbc1f80f86c3eb587a49b1ebf52bb2e3da65158" dependencies = [ "agave-transaction-view", "log", @@ -7732,9 +7726,9 @@ dependencies = [ [[package]] name = "solana-send-transaction-service" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51fb0567093cc4edbd701b995870fc41592fd90e8bc2965ef9f5ce214af22e7" +checksum = "1616c476086eb9c1d80131111b3a6dc7fdbaf844bf594a15daa9c034e1fe68e3" dependencies = [ "crossbeam-channel", "itertools 0.12.1", @@ -7894,9 +7888,9 @@ dependencies = [ [[package]] name = "solana-stake-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabc713c25ff999424ec68ac4572f2ff6bfd6317922c7864435ccaf9c76504a8" +checksum = "2b140dad8a60e40c381a0a359a350d37d51827d02ceb623acf8b942c04f3f3e6" dependencies = [ "bincode", "log", @@ -7923,9 +7917,9 @@ dependencies = [ [[package]] name = "solana-storage-bigtable" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11114c617be52001af7413ee9715b4942d80a0c3de6296061df10da532f6b192" +checksum = "ba94659ad0bf135cf7845543615bd4dbbef0bad02a159250b11e1e4b1b98b891" dependencies = [ "backoff", "bincode", @@ -7965,9 +7959,9 @@ dependencies = [ [[package]] name = "solana-storage-proto" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ed614e38d7327a6a399a17afb3b56c9b7b53fb7222eecdacd9bb73bf8a94d9" +checksum = "4c96c827c82b59f8fab4383a7d79badbc89037f5a237c98d787e339a99bcfe2e" dependencies = [ "bincode", "bs58", @@ -7990,9 +7984,9 @@ dependencies = [ [[package]] name = "solana-streamer" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68441234b1235afb242e7482cabf3e32eb29554e4c4159d5d58e19e54ccfd424" +checksum = "c8251a832b9f849e32266e2ebc14dba374c6c58d64e8b1ea9e9d95e836a53fe6" dependencies = [ "async-channel", "bytes", @@ -8037,9 +8031,9 @@ dependencies = [ [[package]] name = "solana-svm" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850baf834aba4a94a7558fa6cf6ca93fad284abf0363dec5fb9cab173a11fc4" +checksum = "68aae7788fea1a3b85f91be1c260b720ee7496e585a96831bb2a6f4758121e85" dependencies = [ "ahash 0.8.11", "itertools 0.12.1", @@ -8082,18 +8076,18 @@ dependencies = [ [[package]] name = "solana-svm-rent-collector" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa59aea7bfbadb4be9704a6f99c86dbdf48d6204c9291df79ecd6a4f1cc90b59" +checksum = "5bcbacd010528375e02121c48446b0ebe15d5a62e69ef638113ee117280aa18e" dependencies = [ "solana-sdk", ] [[package]] name = "solana-svm-transaction" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fc4392f0eed412141a376e99dfb052069b96f13697a9abb335504babe29387a" +checksum = "1da9eb37e6ced0215a5e44df4ed1f3b885cf349156cbbf99197680cb7eaccf5f" dependencies = [ "solana-hash", "solana-message", @@ -8121,9 +8115,9 @@ dependencies = [ [[package]] name = "solana-system-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c8f684977e4439031b3a27b954ab05a6bdf697d581692aaf8888cf92b73b9e" +checksum = "6321fd5380961387ef4633a98c109ac7f978667ceab2a38d0a699d6ddb2fc57a" dependencies = [ "bincode", "log", @@ -8209,9 +8203,9 @@ dependencies = [ [[package]] name = "solana-test-validator" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723ed26f24b185c36d476b8cd69c1b727ce2074d7342099aa56fce20bec19280" +checksum = "b4d8a955c93f7a0e53bcffdbb850bc19d86dce9dc42f42271057007be39316d8" dependencies = [ "base64 0.22.1", "bincode", @@ -8242,9 +8236,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721a034e94fcfaf8bde1ae4980e7eb58bfeb0c9a243b032b0761fdd19018afbf" +checksum = "61f6e417c23af670d7861ef74feae3c556d47ea9e5f64c664cfcf6d254f43e1a" dependencies = [ "bincode", "log", @@ -8277,9 +8271,9 @@ checksum = "6af261afb0e8c39252a04d026e3ea9c405342b08c871a2ad8aa5448e068c784c" [[package]] name = "solana-timings" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d9eabdce318cb07c60a23f1cc367b43e177c79225b5c2a081869ad182172ad" +checksum = "224f93327d9d3178a30cd6c057e1ac6ca85e95287dd7355064dfa6b9c49f5671" dependencies = [ "eager", "enum-iterator", @@ -8288,9 +8282,9 @@ dependencies = [ [[package]] name = "solana-tls-utils" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a228df037e560a02aac132193f492bdd761e2f90188cd16a440f149882f589b1" +checksum = "ec21c6c242ee93642aa50b829f5727470cdbdf6b461fb7323fe4bc31d1b54c08" dependencies = [ "rustls 0.23.23", "solana-keypair", @@ -8301,9 +8295,9 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaceb9e9349de58740021f826ae72319513eca84ebb6d30326e2604fdad4cefb" +checksum = "637e3ff3c8ece22043d96758f980d95558d50792d827d1457c2e06d9daaa7ff5" dependencies = [ "async-trait", "bincode", @@ -8391,9 +8385,9 @@ dependencies = [ [[package]] name = "solana-transaction-metrics-tracker" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9256ea8a6cead9e03060fd8fdc24d400a57a719364db48a3e4d1776b09c2365" +checksum = "58e40670c0780af24e73551be1fadf2306f61ed13f538ff3933846dab813b06d" dependencies = [ "base64 0.22.1", "bincode", @@ -8408,9 +8402,9 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f739fb4230787b010aa4a49d3feda8b53aac145a9bc3ac2dd44337c6ecb544" +checksum = "e05fc20dd8feb089562b113a80115dab32b22fc64d63ca45c14d7b71e5e98d67" dependencies = [ "Inflector", "base64 0.22.1", @@ -8449,9 +8443,9 @@ dependencies = [ [[package]] name = "solana-transaction-status-client-types" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ac91c8f0465c566164044ad7b3d18d15dfabab1b8b4a4a01cb83c047efdaae" +checksum = "1458fc750d0df4439bb4c1b418a4fe61afbd2e83963e452256eca99dc0c1cf76" dependencies = [ "base64 0.22.1", "bincode", @@ -8472,9 +8466,9 @@ dependencies = [ [[package]] name = "solana-turbine" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a646980cf7729a5f9b01e90a8707eb4b045525c894b538ddf91bd43d216a187" +checksum = "96e387187797c88b3dce71eed5d39d6a14c98b917cc35984b4f0bcabccc5fb16" dependencies = [ "bincode", "bytes", @@ -8514,9 +8508,9 @@ dependencies = [ [[package]] name = "solana-type-overrides" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39dc2e501edfea7ce1cec2fe2a2428aedfea1cc9c31747931e0d90d5c57b020" +checksum = "d26d927bf3ed2f2b6b06a0f409dd8d6b1ad1af73cbba337e9471d05d42f026c9" dependencies = [ "lazy_static", "rand 0.8.5", @@ -8524,9 +8518,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85085c0aa14ebb8e26219386fb7f4348d159f5a67858c2fdefef3cc5f4ce090c" +checksum = "c37955cc627be2745e29ce326fd1b51739e499445b5e2b5fec687ed8ec581e34" dependencies = [ "async-trait", "solana-connection-cache", @@ -8540,9 +8534,9 @@ dependencies = [ [[package]] name = "solana-unified-scheduler-logic" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7e48cbf4e70c05199f50d5f14aafc58331ad39229747c795320bcb362ed063" +checksum = "5c404e2acb884234ae96e0af48b001b6270915e7060d6f70bdec79df5dcaf646" dependencies = [ "assert_matches", "solana-pubkey", @@ -8553,9 +8547,9 @@ dependencies = [ [[package]] name = "solana-unified-scheduler-pool" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9854eb81245123b84af5807731a43aa794961990feaf5a8526127c5898e097" +checksum = "cb9476b2c7981cbbd5f227abf91c9e55ffa8d65894ee10ecb37feef62da49f6d" dependencies = [ "agave-banking-stage-ingress-types", "aquamarine", @@ -8590,9 +8584,9 @@ checksum = "7bbf6d7a3c0b28dd5335c52c0e9eae49d0ae489a8f324917faf0ded65a812c1d" [[package]] name = "solana-version" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f60a01e2721bfd2e094b465440ae461d75acd363e9653565a73d2c586becb3b" +checksum = "374dea09855d46655c776256dda9cc3c854cc70fd923ef22ba0805bc83ca7bfd" dependencies = [ "semver", "serde", @@ -8604,9 +8598,9 @@ dependencies = [ [[package]] name = "solana-vote" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cfd22290c8e63582acd8d8d10670f4de2f81a967b5e9821e2988b4a4d58c54" +checksum = "954d23ac6e7d5e57701870182409b59116543058be82ae9a8ffa9cb9549fa4aa" dependencies = [ "itertools 0.12.1", "log", @@ -8653,9 +8647,9 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab654bb2622d85b2ca0c36cb89c99fa1286268e0d784efec03a3d42e9c6a55f4" +checksum = "e0289c18977992907d361ca94c86cf45fd24cb41169fa03eb84947779e22933f" dependencies = [ "bincode", "log", @@ -8686,9 +8680,9 @@ dependencies = [ [[package]] name = "solana-wen-restart" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23183976f151b510f8ed2f2088c7c47324f2e50a2cca3370faefc2683d0e45d" +checksum = "2b8b3103baee3297fd1ebc302cd3b1142a1cd78dc924dbac40908ddedef7be97" dependencies = [ "anyhow", "log", @@ -8713,9 +8707,9 @@ dependencies = [ [[package]] name = "solana-zk-elgamal-proof-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d241af6328b3e0e20695bb705c850119ec5881b386c338783b8c8bc79e76c65" +checksum = "0a96b0ad864cc4d2156dbf0c4d7cadac4140ae13ebf7e856241500f74eca46f4" dependencies = [ "bytemuck", "num-derive", @@ -8729,9 +8723,9 @@ dependencies = [ [[package]] name = "solana-zk-sdk" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8318220b73552a2765c6545a4be04fc87fe21b6dd0cb8c2b545a66121bf5b8a" +checksum = "71db02a2e496c58840077c96dd4ede61894a4e6053853cca6dcddbb73200fb77" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -8766,9 +8760,9 @@ dependencies = [ [[package]] name = "solana-zk-token-proof-program" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123b7c7d2f9e68190630b216781ca832af0ed78b69acd89a2ad2766cc460c312" +checksum = "c540a4f7df1300dc6087f0cbb271b620dd55e131ea26075bb52ba999be3105f0" dependencies = [ "bytemuck", "num-derive", @@ -8778,14 +8772,14 @@ dependencies = [ "solana-log-collector", "solana-program-runtime", "solana-sdk-ids", - "solana-zk-token-sdk", + "solana-zk-token-sdk 2.2.4", ] [[package]] name = "solana-zk-token-sdk" -version = "2.2.1" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3cf301f8d8e02ef58fc2ce85868f5c760720e1ce74ee4b3c3dcb64c8da7bcff" +checksum = "2c4debebedfebfd4a188a7ac3dd0a56e86368417c35891d6f3c35550b46bfbc0" dependencies = [ "aes-gcm-siv", "base64 0.22.1", @@ -8803,7 +8797,42 @@ dependencies = [ "serde_derive", "serde_json", "sha3", - "solana-curve25519", + "solana-curve25519 2.2.4", + "solana-derivation-path", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-seed-derivable", + "solana-seed-phrase", + "solana-signature", + "solana-signer", + "subtle", + "thiserror 2.0.12", + "zeroize", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "2.3.0" +source = "git+https://github.com/anza-xyz/agave?rev=8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86#8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "lazy_static", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-curve25519 2.3.0", "solana-derivation-path", "solana-instruction", "solana-pubkey", @@ -9181,7 +9210,7 @@ checksum = "170378693c5516090f6d37ae9bad2b9b6125069be68d9acd4865bbe9fc8499fd" dependencies = [ "base64 0.22.1", "bytemuck", - "solana-curve25519", + "solana-curve25519 2.2.4", "solana-zk-sdk", ] @@ -9192,7 +9221,7 @@ source = "git+https://github.com/solana-program/token-2022?rev=00e0f4723c2606c0f dependencies = [ "base64 0.22.1", "bytemuck", - "solana-curve25519", + "solana-curve25519 2.2.4", "solana-zk-sdk", ] @@ -9203,7 +9232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eff2d6a445a147c9d6dd77b8301b1e116c8299601794b558eafa409b342faf96" dependencies = [ "bytemuck", - "solana-curve25519", + "solana-curve25519 2.2.4", "solana-program", "solana-zk-sdk", "spl-pod", @@ -9217,7 +9246,7 @@ source = "git+https://github.com/solana-program/token-2022?rev=00e0f4723c2606c0f dependencies = [ "bytemuck", "solana-account-info", - "solana-curve25519", + "solana-curve25519 2.2.4", "solana-instruction", "solana-instructions-sysvar", "solana-msg", @@ -9351,12 +9380,14 @@ dependencies = [ "solana-cli-output", "solana-client", "solana-commitment-config", + "solana-hash", "solana-instruction", "solana-keypair", "solana-logger", + "solana-presigner", "solana-program-pack", "solana-pubkey", - "solana-remote-wallet", + "solana-remote-wallet 2.3.0", "solana-sdk-ids", "solana-signature", "solana-signer", @@ -9750,20 +9781,6 @@ dependencies = [ "syn 2.0.99", ] -[[package]] -name = "thread-priority" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe075d7053dae61ac5413a34ea7d4913b6e6207844fd726bdd858b37ff72bf5" -dependencies = [ - "bitflags 2.9.0", - "cfg-if 1.0.0", - "libc", - "log", - "rustversion", - "winapi 0.3.9", -] - [[package]] name = "thread_local" version = "1.1.8" @@ -9988,26 +10005,11 @@ dependencies = [ "serde", ] -[[package]] -name = "toml" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -10016,8 +10018,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap 2.7.1", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 479a1f79..0b375f94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,6 @@ serde_with = "3.12.0" serial_test = "3.2.0" solana-account = "2.2.1" solana-account-info = "2.2.1" -solana-clap-v3-utils = "2.2.1" solana-cli-config = "2.2.1" solana-cli-output = "2.2.1" solana-client = "2.2.1" @@ -51,15 +50,16 @@ solana-commitment-config = "2.2.1" solana-cpi = "2.2.1" solana-decode-error = "2.2.1" solana-logger = "2.2.1" +solana-hash = "2.2.1" solana-instruction = "2.2.1" solana-keypair = "2.2.1" solana-msg = "2.2.1" +solana-presigner = "2.2.1" solana-program-entrypoint = "2.2.1" solana-program-error = "2.2.1" solana-program-option = "2.2.1" solana-program-pack = "2.2.1" solana-pubkey = "2.2.1" -solana-remote-wallet = "2.2.1" solana-rent = "2.2.1" solana-sdk-ids = "2.2.1" solana-signature = "2.2.1" @@ -82,3 +82,8 @@ tokio = { version = "1.44.1", features = ["full"] } # Should depend on the next crate version after 7.0.0 when https://github.com/solana-program/token-2022/pull/253 is deployed spl-token-2022 = { git = "https://github.com/solana-program/token-2022", rev = "00e0f4723c2606c0facbb4921e1b2e2e030d1fa6", features = ["no-entrypoint"] } + +# Should depend on next version of these packages after https://github.com/anza-xyz/agave/pull/5534 is deployed +solana-clap-v3-utils = { git = "https://github.com/anza-xyz/agave", package = "solana-clap-v3-utils", rev = "8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" } +# Need to specify same commit as above for type compatiblity +solana-remote-wallet = { git = "https://github.com/anza-xyz/agave", package = "solana-remote-wallet", rev = "8cf1f8dbf36b2d7b083d5e9883f51282b2cb7c86" } diff --git a/clients/cli/Cargo.toml b/clients/cli/Cargo.toml index 8e158061..5a524a2f 100644 --- a/clients/cli/Cargo.toml +++ b/clients/cli/Cargo.toml @@ -18,8 +18,10 @@ solana-cli-config = { workspace = true } solana-cli-output = { workspace = true } solana-client = { workspace = true } solana-commitment-config = { workspace = true } +solana-hash = { workspace = true } solana-instruction = { workspace = true } solana-logger = { workspace = true } +solana-presigner = { workspace = true } solana-program-pack = { workspace = true } solana-pubkey = { workspace = true } solana-remote-wallet = { workspace = true } diff --git a/clients/cli/src/cli.rs b/clients/cli/src/cli.rs index 3d5b4b3a..9f2a4b5c 100644 --- a/clients/cli/src/cli.rs +++ b/clients/cli/src/cli.rs @@ -82,6 +82,7 @@ pub struct Cli { pub output_format: Option, } +#[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, Subcommand)] pub enum Command { /// Create a wrapped mint for a given SPL Token diff --git a/clients/cli/src/common.rs b/clients/cli/src/common.rs index 26d6edb6..91f530a7 100644 --- a/clients/cli/src/common.rs +++ b/clients/cli/src/common.rs @@ -2,9 +2,11 @@ use { crate::{config::Config, output::println_display, Error}, clap::ArgMatches, solana_clap_v3_utils::keypair::pubkey_from_path, + solana_presigner::Presigner, solana_pubkey::Pubkey, solana_signature::Signature, solana_transaction::Transaction, + std::str::FromStr, }; pub fn parse_pubkey(value: &str) -> Result { @@ -26,6 +28,17 @@ pub fn parse_token_program(value: &str) -> Result { } } +pub fn parse_presigner(value: &str) -> Result { + let (pubkey_string, sig_string) = value + .split_once('=') + .ok_or("failed to split `pubkey=signature` pair")?; + let pubkey = Pubkey::from_str(pubkey_string) + .map_err(|_| "Failed to parse pubkey from string".to_string())?; + let sig = Signature::from_str(sig_string) + .map_err(|_| "Failed to parse signature from string".to_string())?; + Ok(Presigner::new(&pubkey, &sig)) +} + pub async fn process_transaction( config: &Config, transaction: Transaction, diff --git a/clients/cli/src/config.rs b/clients/cli/src/config.rs index 5840ad07..9009f422 100644 --- a/clients/cli/src/config.rs +++ b/clients/cli/src/config.rs @@ -2,7 +2,9 @@ use { crate::{cli::Cli, Error}, anyhow::anyhow, clap::ArgMatches, - solana_clap_v3_utils::keypair::{signer_from_path, signer_from_source}, + solana_clap_v3_utils::keypair::{ + signer_from_path, signer_from_source_with_config, SignerFromPathConfig, + }, solana_cli_output::OutputFormat, solana_client::nonblocking::rpc_client::RpcClient, solana_commitment_config::CommitmentConfig, @@ -39,13 +41,19 @@ impl Config { )); let fee_payer = match &cli.fee_payer { - Some(fee_payer_source) => { - signer_from_source(&matches, fee_payer_source, "fee_payer", wallet_manager) - } + Some(fee_payer_source) => signer_from_source_with_config( + &matches, + fee_payer_source, + "fee_payer", + wallet_manager, + &SignerFromPathConfig { + allow_null_signer: true, + }, + ), None => signer_from_path( &matches, &cli_config.keypair_path, - "default", + "fee_payer", wallet_manager, ), } diff --git a/clients/cli/src/wrap.rs b/clients/cli/src/wrap.rs index 4994682f..f0093df6 100644 --- a/clients/cli/src/wrap.rs +++ b/clients/cli/src/wrap.rs @@ -1,15 +1,24 @@ use { crate::{ - common::{parse_pubkey, parse_token_program, process_transaction}, + common::{parse_presigner, parse_pubkey, parse_token_program, process_transaction}, config::Config, output::{format_output, println_display}, CommandResult, Error, }, - clap::Args, + clap::{value_parser, Args}, serde_derive::{Deserialize, Serialize}, serde_with::{serde_as, DisplayFromStr}, - solana_cli_output::{display::writeln_name_value, QuietDisplay, VerboseDisplay}, + solana_clap_v3_utils::{ + input_parsers::signer::{SignerSource, SignerSourceParserBuilder}, + keypair::{signer_from_source_with_config, SignerFromPathConfig}, + }, + solana_cli_output::{ + display::writeln_name_value, return_signers_data, CliSignOnlyData, QuietDisplay, + ReturnSignersConfig, VerboseDisplay, + }, solana_client::nonblocking::rpc_client::RpcClient, + solana_hash::Hash, + solana_presigner::Presigner, solana_pubkey::Pubkey, solana_remote_wallet::remote_wallet::RemoteWalletManager, solana_signature::Signature, @@ -43,10 +52,12 @@ pub struct WrapArgs { #[clap(value_parser)] pub amount: u64, - /// Path to the signer for the transfer authority if different from - /// fee payer - #[clap(long, value_name = "PATH")] - pub transfer_authority: Option, + /// Signer source of transfer authority if different from fee payer + #[clap( + long, + value_parser = SignerSourceParserBuilder::default().allow_all().build() + )] + pub transfer_authority: Option, /// The address of the mint to wrap, queried if not provided #[clap(long, value_parser = parse_pubkey)] @@ -61,6 +72,33 @@ pub struct WrapArgs { /// Queries account for `unwrapped_token_account` if not provided. #[clap(long, value_parser = parse_token_program)] pub unwrapped_token_program: Option, + + /// Member signer of a multisig account. + /// Use this argument multiple times for each signer. + #[clap( + long, + multiple = true, + value_parser = SignerSourceParserBuilder::default().allow_all().build(), + requires = "blockhash" + )] + pub multisig_signer: Option>, + + #[clap(long, value_parser = value_parser!(Hash))] + pub blockhash: Option, + + /// Signatures to add to transaction. + /// Often the `PUBKEY=SIGNATURE` output from a multisig --sign-only signer. + #[clap( + long, + multiple = true, + value_parser = parse_presigner, + requires = "blockhash" + )] + pub signer: Option>, + + /// Do not broadcast signed transaction, just sign + #[clap(long)] + pub sign_only: bool, } #[serde_as] @@ -69,17 +107,24 @@ pub struct WrapArgs { pub struct WrapOutput { #[serde_as(as = "DisplayFromStr")] pub unwrapped_mint_address: Pubkey, + #[serde_as(as = "DisplayFromStr")] pub wrapped_mint_address: Pubkey, + #[serde_as(as = "DisplayFromStr")] pub unwrapped_token_account: Pubkey, + #[serde_as(as = "DisplayFromStr")] pub recipient_token_account: Pubkey, + #[serde_as(as = "DisplayFromStr")] pub escrow_account: Pubkey, + pub amount: u64, - #[serde_as(as = "Option")] - pub signature: Option, + + pub signatures: Vec, + + pub sign_only_data: Option, } impl Display for WrapOutput { @@ -106,9 +151,16 @@ impl Display for WrapOutput { )?; writeln_name_value(f, "Escrow account:", &self.escrow_account.to_string())?; writeln_name_value(f, "Amount:", &self.amount.to_string())?; - if let Some(signature) = self.signature { - writeln_name_value(f, "Signature:", &signature.to_string())?; + + if let Some(data) = &self.sign_only_data { + writeln!(f, "{}", data)?; + } else { + writeln!(f, "Signers:")?; + for signature in &self.signatures { + writeln!(f, " {signature}")?; + } } + Ok(()) } } @@ -143,13 +195,15 @@ pub async fn command_wrap( get_unwrapped_mint(&config.rpc_client, &args.unwrapped_token_account).await? }; - println_display( - config, - format!( - "Wrapping {} tokens from mint {}", - args.amount, unwrapped_mint - ), - ); + if !args.sign_only { + println_display( + config, + format!( + "Wrapping {} tokens from mint {}", + args.amount, unwrapped_mint + ), + ); + } // Derive wrapped mint address and mint authority let wrapped_mint_address = @@ -165,14 +219,20 @@ pub async fn command_wrap( ) }); + // NullSigner used for multisig scenarios + let parse_config = SignerFromPathConfig { + allow_null_signer: true, + }; + // If transfer_authority is provided, use it as a signer, // else default to fee payer let transfer_authority_signer = if let Some(authority_keypair_path) = &args.transfer_authority { - let signer = solana_clap_v3_utils::keypair::signer_from_path( + let signer = signer_from_source_with_config( matches, authority_keypair_path, - "transfer-authority", + "transfer_authority", wallet_manager, + &parse_config, ) .map_err(|e| e.to_string())?; Arc::from(signer) @@ -180,6 +240,26 @@ pub async fn command_wrap( payer.clone() }; + let mut multisig_signers: Vec> = vec![]; + if let Some(sources) = &args.multisig_signer { + for source in sources { + let signer = signer_from_source_with_config( + matches, + source, + "multisig_signer", + wallet_manager, + &parse_config, + ) + .map_err(|e| e.to_string())?; + multisig_signers.push(Arc::from(signer)); + } + } + + let multisig_pubkeys = multisig_signers + .iter() + .map(|s| s.pubkey()) + .collect::>(); + let unwrapped_token_program = if let Some(pubkey) = args.unwrapped_token_program { pubkey } else { @@ -201,25 +281,51 @@ pub async fn command_wrap( &unwrapped_mint, &args.escrow_account, &transfer_authority_signer.pubkey(), - &[], // TODO: Add multisig support + &multisig_pubkeys.iter().collect::>(), args.amount, ); - let latest_blockhash = config.rpc_client.get_latest_blockhash().await?; - let mut signers = vec![payer.as_ref()]; + let blockhash = if let Some(hash) = args.blockhash { + hash + } else { + config.rpc_client.get_latest_blockhash().await? + }; - if payer.pubkey() != transfer_authority_signer.pubkey() { - signers.push(transfer_authority_signer.as_ref()); + // Payer will always be a signer + let mut signers = vec![payer.clone()]; + + // In the case that a transfer_authority is passed (otherwise defaults to + // payer), it needs to be added to signers if it isn't a multisig. + if payer.pubkey() != transfer_authority_signer.pubkey() && multisig_signers.is_empty() { + signers.push(transfer_authority_signer); } - let transaction = Transaction::new_signed_with_payer( - &[instruction], - Some(&payer.pubkey()), - &signers, - latest_blockhash, - ); + for signer in &multisig_signers { + signers.push(signer.clone()); + } + + // Pre-signed transactions can be passed as --signer `PUBKEY=SIGNATURE` + if let Some(pre_signers) = &args.signer { + for signer in pre_signers { + signers.push(Arc::from(signer)); + } + } + + let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey())); + transaction.partial_sign(&signers, blockhash); - let signature = process_transaction(config, transaction).await?; + if !args.sign_only { + process_transaction(config, transaction.clone()).await?; + } + + let sign_only_data = args.sign_only.then(|| { + return_signers_data( + &transaction, + &ReturnSignersConfig { + dump_transaction_message: true, + }, + ) + }); let output = WrapOutput { unwrapped_mint_address: unwrapped_mint, @@ -228,7 +334,8 @@ pub async fn command_wrap( recipient_token_account, escrow_account: args.escrow_account, amount: args.amount, - signature, + signatures: transaction.signatures, + sign_only_data, }; Ok(format_output(config, output)) diff --git a/clients/cli/tests/helpers.rs b/clients/cli/tests/helpers.rs index a195c10f..e2ae21a2 100644 --- a/clients/cli/tests/helpers.rs +++ b/clients/cli/tests/helpers.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use { + serde_json::Value, solana_cli_config::Config as SolanaConfig, solana_client::nonblocking::rpc_client::RpcClient, solana_keypair::{write_keypair_file, Keypair}, @@ -8,11 +9,12 @@ use { solana_pubkey::Pubkey, solana_sdk_ids::bpf_loader_upgradeable, solana_signer::Signer, + solana_system_interface::instruction::create_account, solana_test_validator::{TestValidator, TestValidatorGenesis, UpgradeableProgramInfo}, solana_transaction::Transaction, spl_associated_token_account_client::address::get_associated_token_address_with_program_id, spl_token::{self, instruction::initialize_mint, state::Mint as SplTokenMint}, - std::{path::PathBuf, process::Command, sync::Arc}, + std::{error::Error, path::PathBuf, process::Command, sync::Arc}, tempfile::NamedTempFile, }; @@ -133,49 +135,6 @@ pub async fn execute_create_mint( assert!(status.success()); } -#[allow(clippy::too_many_arguments)] -pub async fn execute_wrap( - env: &TestEnv, - unwrapped_token_account: &Pubkey, - escrow_account: &Pubkey, - wrapped_token_program: &Pubkey, - amount: u64, - unwrapped_token_program: Option<&Pubkey>, - mint_address: Option<&Pubkey>, - recipient_account: Option<&Pubkey>, -) { - let mut args = vec![ - "wrap".to_string(), - "-C".to_string(), - env.config_file_path.clone(), - unwrapped_token_account.to_string(), - escrow_account.to_string(), - wrapped_token_program.to_string(), - amount.to_string(), - ]; - - if let Some(program) = unwrapped_token_program { - args.push("--unwrapped-token-program".to_string()); - args.push(program.to_string()); - } - - if let Some(mint) = mint_address { - args.push("--unwrapped-mint".to_string()); - args.push(mint.to_string()); - } - - if let Some(recipient) = recipient_account { - args.push("--recipient-token-account".to_string()); - args.push(recipient.to_string()); - } - - let status = Command::new(TOKEN_WRAP_CLI_BIN) - .args(args) - .status() - .unwrap(); - assert!(status.success()); -} - pub async fn create_associated_token_account( env: &TestEnv, token_program: &Pubkey, @@ -279,3 +238,71 @@ pub async fn mint_to( .await .unwrap(); } + +// Creates 2 of 3 multisig +pub async fn create_test_multisig( + env: &mut TestEnv, +) -> Result<(Pubkey, Vec), Box> { + let multisig_keypair = Keypair::new(); + let multisig_pubkey = multisig_keypair.pubkey(); + let multisig_member1 = Keypair::new(); + let multisig_member2 = Keypair::new(); + let multisig_member3 = Keypair::new(); + let multisig_member_pubkeys = [ + &multisig_member1.pubkey(), + &multisig_member2.pubkey(), + &multisig_member3.pubkey(), + ]; + + let rent = env + .rpc_client + .get_minimum_balance_for_rent_exemption(spl_token::state::Multisig::LEN) + .await?; + + let create_account_instruction = create_account( + &env.payer.pubkey(), + &multisig_pubkey, + rent, + spl_token::state::Multisig::LEN as u64, + &spl_token::id(), + ); + + let initialize_multisig_instruction = spl_token::instruction::initialize_multisig( + &spl_token::id(), + &multisig_pubkey, + &multisig_member_pubkeys, + 2, + )?; + + let mut transaction = Transaction::new_with_payer( + &[create_account_instruction, initialize_multisig_instruction], + Some(&env.payer.pubkey()), + ); + let recent_blockhash = env.rpc_client.get_latest_blockhash().await?; + transaction.sign(&[&env.payer, &multisig_keypair], recent_blockhash); + + env.rpc_client + .send_and_confirm_transaction(&transaction) + .await?; + + Ok(( + multisig_pubkey, + vec![multisig_member1, multisig_member2, multisig_member3], + )) +} + +// Used to get signers vec from CLI output +pub fn extract_signers(std_out: &[u8]) -> Vec { + let json_output1 = String::from_utf8(std_out.to_vec()).unwrap(); + let parsed_value: Value = serde_json::from_str(&json_output1).unwrap(); + parsed_value + .get("signOnlyData") + .unwrap() + .get("signers") + .unwrap() + .as_array() + .unwrap() + .iter() + .map(|v| v.as_str().unwrap().to_string()) + .collect() +} diff --git a/clients/cli/tests/test_wrap.rs b/clients/cli/tests/test_wrap.rs index 9bcdd590..37572cd2 100644 --- a/clients/cli/tests/test_wrap.rs +++ b/clients/cli/tests/test_wrap.rs @@ -1,14 +1,18 @@ use { crate::helpers::{ - create_associated_token_account, create_token_account, create_unwrapped_mint, - execute_create_mint, execute_wrap, mint_to, setup_test_env, TestEnv, + create_associated_token_account, create_test_multisig, create_token_account, + create_unwrapped_mint, execute_create_mint, extract_signers, mint_to, setup_test_env, + TestEnv, TOKEN_WRAP_CLI_BIN, }, serial_test::serial, + solana_keypair::{write_keypair_file, Keypair}, solana_pubkey::Pubkey, solana_signer::Signer, spl_token::{self}, spl_token_2022::{extension::PodStateWithExtensions, pod::PodAccount}, spl_token_wrap::{get_wrapped_mint_address, get_wrapped_mint_authority}, + std::process::Command, + tempfile::NamedTempFile, }; mod helpers; @@ -64,18 +68,21 @@ async fn test_wrap_single_signer_with_defaults() { .await; // Execute wrap instruction - let unwrap_amount = 50; - execute_wrap( - &env, - &unwrapped_token_account, - &escrow_account, - &wrapped_token_program, - unwrap_amount, - None, - None, - None, - ) - .await; + let wrap_amount = 50; + + let status = Command::new(TOKEN_WRAP_CLI_BIN) + .args(vec![ + "wrap".to_string(), + "-C".to_string(), + env.config_file_path.clone(), + unwrapped_token_account.to_string(), + escrow_account.to_string(), + wrapped_token_program.to_string(), + wrap_amount.to_string(), + ]) + .status() + .unwrap(); + assert!(status.success()); assert_result( env, @@ -83,7 +90,7 @@ async fn test_wrap_single_signer_with_defaults() { starting_amount, &recipient_account, &escrow_account, - unwrap_amount, + wrap_amount, ) .await; } @@ -105,12 +112,16 @@ async fn test_wrap_single_signer_with_optional_flags() { ) .await; + let transfer_authority = Keypair::new(); + let authority_keypair_file = NamedTempFile::new().unwrap(); + write_keypair_file(&transfer_authority, &authority_keypair_file).unwrap(); + // Fund initial unwrapped token account let unwrapped_token_account = create_token_account( &env, &unwrapped_token_program, &unwrapped_mint, - &env.payer.pubkey(), + &transfer_authority.pubkey(), ) .await; let starting_amount = 100; @@ -145,18 +156,29 @@ async fn test_wrap_single_signer_with_optional_flags() { .await; // Execute wrap instruction - let unwrap_amount = 50; - execute_wrap( - &env, - &unwrapped_token_account, - &escrow_account, - &wrapped_token_program, - unwrap_amount, - Some(&unwrapped_token_program), - Some(&unwrapped_mint), - Some(&recipient_account), - ) - .await; + let wrap_amount = 50; + + let status = Command::new(TOKEN_WRAP_CLI_BIN) + .args(vec![ + "wrap".to_string(), + "-C".to_string(), + env.config_file_path.clone(), + unwrapped_token_account.to_string(), + escrow_account.to_string(), + wrapped_token_program.to_string(), + wrap_amount.to_string(), + "--unwrapped-token-program".to_string(), + unwrapped_token_program.to_string(), + "--unwrapped-mint".to_string(), + unwrapped_mint.to_string(), + "--recipient-token-account".to_string(), + recipient_account.to_string(), + "--transfer-authority".to_string(), + authority_keypair_file.path().to_str().unwrap().to_string(), + ]) + .status() + .unwrap(); + assert!(status.success()); assert_result( env, @@ -164,7 +186,7 @@ async fn test_wrap_single_signer_with_optional_flags() { starting_amount, &recipient_account, &escrow_account, - unwrap_amount, + wrap_amount, ) .await; } @@ -175,7 +197,7 @@ async fn assert_result( starting_amount: u64, recipient_account: &Pubkey, escrow_account: &Pubkey, - unwrap_amount: u64, + wrap_amount: u64, ) { let unwrapped_account_data = env .rpc_client @@ -188,7 +210,7 @@ async fn assert_result( // Unwrapped token account should be lower assert_eq!( u64::from(unwrapped_token_state.base.amount), - starting_amount.checked_sub(unwrap_amount).unwrap() + starting_amount.checked_sub(wrap_amount).unwrap() ); // Escrow account should have the tokens @@ -199,12 +221,206 @@ async fn assert_result( .unwrap(); let escrow_token_state = PodStateWithExtensions::::unpack(&escrow_account_data).unwrap(); - assert_eq!(u64::from(escrow_token_state.base.amount), unwrap_amount); + assert_eq!(u64::from(escrow_token_state.base.amount), wrap_amount); // Recipient should have wrapped tokens let wrapped_account = env.rpc_client.get_account(recipient_account).await.unwrap(); assert_eq!(wrapped_account.owner, spl_token_2022::id()); let wrapped_token_state = PodStateWithExtensions::::unpack(&wrapped_account.data).unwrap(); - assert_eq!(u64::from(wrapped_token_state.base.amount), unwrap_amount); + assert_eq!(u64::from(wrapped_token_state.base.amount), wrap_amount); +} + +#[tokio::test] +#[serial] +async fn test_wrap_with_multisig() { + let mut env = setup_test_env().await; + + let (multisig_pubkey, multisig_members) = create_test_multisig(&mut env).await.unwrap(); + + let unwrapped_token_program = spl_token::id(); + let wrapped_token_program = spl_token_2022::id(); + + let unwrapped_mint = create_unwrapped_mint(&env, &unwrapped_token_program).await; + + execute_create_mint( + &env, + &unwrapped_mint, + &unwrapped_token_program, + &wrapped_token_program, + ) + .await; + + let unwrapped_token_account = create_token_account( + &env, + &unwrapped_token_program, + &unwrapped_mint, + &multisig_pubkey, + ) + .await; + + let starting_amount = 100; + mint_to( + &env, + &unwrapped_token_program, + &unwrapped_mint, + &unwrapped_token_account, + starting_amount, + ) + .await; + + let wrapped_mint = get_wrapped_mint_address(&unwrapped_mint, &wrapped_token_program); + let recipient_account = + create_associated_token_account(&env, &wrapped_token_program, &wrapped_mint).await; + + let wrapped_mint_authority = get_wrapped_mint_authority(&wrapped_mint); + let escrow_account = create_token_account( + &env, + &unwrapped_token_program, + &unwrapped_mint, + &wrapped_mint_authority, + ) + .await; + + let wrap_amount = 50; + + let multisig_member_1 = multisig_members.first().unwrap(); + let member_1_keypair_file = NamedTempFile::new().unwrap(); + write_keypair_file(multisig_member_1, &member_1_keypair_file).unwrap(); + + let multisig_member_2 = multisig_members.get(1).unwrap(); + let member_2_keypair_file = NamedTempFile::new().unwrap(); + write_keypair_file(multisig_member_2, &member_2_keypair_file).unwrap(); + + let blockhash = env.rpc_client.get_latest_blockhash().await.unwrap(); + + // --- Signer 1 --- + // multisig member #1 passes their keypair and the pubkeys + // for multisig member #2 and fee payer + let output1 = Command::new(TOKEN_WRAP_CLI_BIN) + .args(vec![ + "wrap".to_string(), + "-C".to_string(), + env.config_file_path.clone(), + unwrapped_token_account.to_string(), + escrow_account.to_string(), + wrapped_token_program.to_string(), + wrap_amount.to_string(), + "--fee-payer".to_string(), + env.payer.pubkey().to_string(), + "--recipient-token-account".to_string(), + recipient_account.to_string(), + "--transfer-authority".to_string(), + multisig_pubkey.to_string(), + "--multisig-signer".to_string(), + member_1_keypair_file.path().to_str().unwrap().to_string(), + "--multisig-signer".to_string(), + multisig_member_2.pubkey().to_string(), + "--blockhash".to_string(), + blockhash.to_string(), + "--sign-only".to_string(), + "--output".to_string(), + "json".to_string(), + ]) + .output() + .unwrap(); + + if !output1.status.success() { + let stderr = String::from_utf8_lossy(&output1.stderr); + let stdout = String::from_utf8_lossy(&output1.stdout); + panic!( + "output1 failed with status: {}\nStdout: {}\nStderr: {}", + output1.status, stdout, stderr + ); + } + + let signers1 = extract_signers(&output1.stdout); + assert_eq!(signers1.len(), 1); + let member_1_signature = signers1.first().cloned().unwrap(); + + // --- Signer 2 --- + // multisig member #2 passes their keypair and the pubkeys + // for multisig member #1 and fee payer + let output2 = Command::new(TOKEN_WRAP_CLI_BIN) + .args(vec![ + "wrap".to_string(), + "-C".to_string(), + env.config_file_path.clone(), + unwrapped_token_account.to_string(), + escrow_account.to_string(), + wrapped_token_program.to_string(), + wrap_amount.to_string(), + "--fee-payer".to_string(), + env.payer.pubkey().to_string(), + "--recipient-token-account".to_string(), + recipient_account.to_string(), + "--transfer-authority".to_string(), + multisig_pubkey.to_string(), + "--multisig-signer".to_string(), + multisig_member_1.pubkey().to_string(), + "--multisig-signer".to_string(), + member_2_keypair_file.path().to_str().unwrap().to_string(), + "--blockhash".to_string(), + blockhash.to_string(), + "--sign-only".to_string(), + "--output".to_string(), + "json".to_string(), + ]) + .output() + .unwrap(); + + if !output2.status.success() { + let stderr = String::from_utf8_lossy(&output1.stderr); + let stdout = String::from_utf8_lossy(&output1.stdout); + panic!( + "output2 failed with exit code: {}\nStdout: {}\nStderr: {}", + output2.status, stdout, stderr + ); + } + + let signers2 = extract_signers(&output2.stdout); + assert_eq!(signers2.len(), 1); + let member_2_signature = signers2.first().cloned().unwrap(); + + // --- Final Broadcaster --- + // Passes the keypair for feepayer (default behavior) + // and the signatures for member #1 & #2 + let status = Command::new(TOKEN_WRAP_CLI_BIN) + .args(vec![ + "wrap".to_string(), + "-C".to_string(), + env.config_file_path.clone(), + unwrapped_token_account.to_string(), + escrow_account.to_string(), + wrapped_token_program.to_string(), + wrap_amount.to_string(), + "--recipient-token-account".to_string(), + recipient_account.to_string(), + "--transfer-authority".to_string(), + multisig_pubkey.to_string(), + "--multisig-signer".to_string(), + multisig_member_1.pubkey().to_string(), + "--multisig-signer".to_string(), + multisig_member_2.pubkey().to_string(), + "--blockhash".to_string(), + blockhash.to_string(), + "--signer".to_string(), + member_1_signature, + "--signer".to_string(), + member_2_signature, + ]) + .status() + .unwrap(); + assert!(status.success()); + + // Verify the results of the wrap transaction + assert_result( + env, + &unwrapped_token_account, + starting_amount, + &recipient_account, + &escrow_account, + wrap_amount, + ) + .await; }