diff --git a/.gitignore b/.gitignore index 2a0038a..1b9cbf1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -.idea \ No newline at end of file +.idea +*.hex diff --git a/Cargo.lock b/Cargo.lock index f65b2a2..1947458 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,6 +69,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "const-random", "getrandom 0.3.3", "once_cell", "version_check", @@ -1638,6 +1639,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "static_assertions", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -2080,6 +2090,7 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", + "serde", ] [[package]] @@ -2415,7 +2426,7 @@ checksum = "803d15461ab0dcc56706adf266158acbc44ccf719bf7d0af30705f58b90a4b8c" dependencies = [ "integer-sqrt", "num-traits", - "uint", + "uint 0.10.0", ] [[package]] @@ -2738,13 +2749,23 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2bd4c29270e724d3eaadf7bdc8700af4221fc0ed771b855eadcd1b98d52851" +dependencies = [ + "primitive-types 0.10.1", + "tiny-keccak", +] + [[package]] name = "keccak-hash" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e1b8590eb6148af2ea2d75f38e7d29f5ca970d5a4df456b3ef19b8b415d0264" dependencies = [ - "primitive-types", + "primitive-types 0.13.1", "tiny-keccak", ] @@ -3022,6 +3043,20 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -3030,6 +3065,17 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "rand 0.8.5", ] [[package]] @@ -3057,6 +3103,17 @@ 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.4.2" @@ -3420,6 +3477,18 @@ dependencies = [ "spki", ] +[[package]] +name = "plonky2_maybe_rayon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1e554181dc95243b8d9948ae7bae5759c7fb2502fed28f671f95ef38079406" + +[[package]] +name = "plonky2_util" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c32c137808ca984ab2458b612b7eb0462d853ee041a3136e83d54b96074c7610" + [[package]] name = "polkavm-common" version = "0.24.0" @@ -3534,18 +3603,28 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "uint 0.9.5", +] + [[package]] name = "primitive-types" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" dependencies = [ - "fixed-hash", + "fixed-hash 0.8.0", "impl-codec", "impl-num-traits", "impl-serde", "scale-info", - "uint", + "uint 0.10.0", ] [[package]] @@ -3645,7 +3724,7 @@ checksum = "fb2f13d8793f7a79c42d33e4ebe9d470fe938dc55592ef97ef42d4298aa6a976" dependencies = [ "log", "parity-scale-codec", - "qp-poseidon 1.0.1", + "qp-poseidon", "qp-rusty-crystals-dilithium", "qp-rusty-crystals-hdwallet", "scale-info", @@ -3656,35 +3735,59 @@ dependencies = [ ] [[package]] -name = "qp-poseidon" -version = "0.9.5" +name = "qp-plonky2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33181134496120c212a0a2098215cf45a68d50fe656de6fb30b31e73babe9383" +checksum = "39530b02faa85964bba211e030afa2d54995b403b0022f88e984c4c65679c4bc" dependencies = [ + "ahash", + "anyhow", + "hashbrown 0.14.5", + "itertools 0.11.0", + "keccak-hash 0.8.0", "log", + "num", "p3-field", "p3-goldilocks", - "parity-scale-codec", - "qp-poseidon-core 0.9.5", - "scale-info", + "p3-poseidon2", + "p3-symmetric", + "plonky2_maybe_rayon", + "plonky2_util", + "qp-plonky2-field", + "qp-poseidon-constants", + "rand 0.8.5", "serde", - "sp-core", - "sp-runtime", - "sp-storage", - "sp-trie", + "static_assertions", + "unroll", +] + +[[package]] +name = "qp-plonky2-field" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8d52dadf3bb92708c309922b62d7f3f2587d3047f9fe05a0c9f587e2890526" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "num", + "plonky2_util", + "rustc_version", + "serde", + "static_assertions", + "unroll", ] [[package]] name = "qp-poseidon" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0353086f7af1df7d45a1ecb995cf84b583c8211d7122f542044b37388b5effcd" +checksum = "fef3bb816fc51b4ffc4524fa03376037d2531b17e2349ef6489a417cef029b3a" dependencies = [ "log", "p3-field", "p3-goldilocks", "parity-scale-codec", - "qp-poseidon-core 1.0.1", + "qp-poseidon-core", "scale-info", "serde", "sp-core", @@ -3708,28 +3811,15 @@ dependencies = [ [[package]] name = "qp-poseidon-core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec326fc2631a929de09a38af2613a3db5230882c12a2f68205693ec632751e8b" -dependencies = [ - "p3-field", - "p3-goldilocks", - "p3-poseidon2", - "p3-symmetric", - "rand 0.9.2", - "rand_chacha 0.9.0", -] - -[[package]] -name = "qp-poseidon-core" -version = "1.0.1" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e658a373a7fb22babeda9ffcc8af0a894e6e3c008272ed735509eccb7769ead3" +checksum = "e33b3fb9032ac9b197265da8fc8bdedd21ba76592ceefbf4a591286d47baec2d" dependencies = [ "p3-field", "p3-goldilocks", "p3-poseidon2", "p3-symmetric", + "qp-plonky2", "qp-poseidon-constants", "rand_chacha 0.9.0", ] @@ -3756,7 +3846,7 @@ dependencies = [ "hex", "hex-literal", "nam-tiny-hderive", - "qp-poseidon-core 1.0.1", + "qp-poseidon-core", "qp-rusty-crystals-dilithium", "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -3765,11 +3855,50 @@ dependencies = [ "thiserror 2.0.16", ] +[[package]] +name = "qp-wormhole-circuit" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcbccee20e314a1c52f36d8e78b1fa8205da46050c18da60d4964f41875bd4f6" +dependencies = [ + "anyhow", + "hex", + "qp-plonky2", + "qp-poseidon-core", + "qp-zk-circuits-common", +] + +[[package]] +name = "qp-wormhole-prover" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd377a2fa936e6edb069ffecbf41afe10803b342e5cda8ff3aab199f77fde5d" +dependencies = [ + "anyhow", + "qp-plonky2", + "qp-wormhole-circuit", + "qp-zk-circuits-common", +] + +[[package]] +name = "qp-zk-circuits-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445cc21c39959d1b553c4d8ea94d058ceab84cd70e5d47ec82b11535494cec46" +dependencies = [ + "anyhow", + "hex", + "qp-plonky2", + "qp-poseidon-core", + "serde", +] + [[package]] name = "quantus-cli" version = "0.3.1" dependencies = [ "aes-gcm", + "anyhow", "argon2", "chrono", "clap", @@ -3781,9 +3910,14 @@ dependencies = [ "jsonrpsee", "parity-scale-codec", "qp-dilithium-crypto", - "qp-poseidon 0.9.5", + "qp-plonky2", + "qp-poseidon", + "qp-poseidon-core", "qp-rusty-crystals-dilithium", "qp-rusty-crystals-hdwallet", + "qp-wormhole-circuit", + "qp-wormhole-prover", + "qp-zk-circuits-common", "rand 0.9.2", "rpassword", "serde", @@ -4153,7 +4287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d78196772d25b90a98046794ce0fe2588b39ebdfbdc1e45b4c6c85dd43bebad" dependencies = [ "parity-scale-codec", - "primitive-types", + "primitive-types 0.13.1", "scale-bits", "scale-decode-derive", "scale-type-resolver", @@ -4180,7 +4314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64901733157f9d25ef86843bd783eda439fac7efb0ad5a615d12d2cf3a29464b" dependencies = [ "parity-scale-codec", - "primitive-types", + "primitive-types 0.13.1", "scale-bits", "scale-encode-derive", "scale-type-resolver", @@ -4788,7 +4922,7 @@ dependencies = [ "parity-scale-codec", "parking_lot", "paste", - "primitive-types", + "primitive-types 0.13.1", "rand 0.8.5", "scale-info", "schnorrkel", @@ -4984,7 +5118,7 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "polkavm-derive", - "primitive-types", + "primitive-types 0.13.1", "sp-externalities", "sp-runtime-interface-proc-macro", "sp-std", @@ -5261,7 +5395,7 @@ dependencies = [ "hex", "jsonrpsee", "parity-scale-codec", - "primitive-types", + "primitive-types 0.13.1", "scale-bits", "scale-decode", "scale-encode", @@ -5315,9 +5449,9 @@ dependencies = [ "hashbrown 0.14.5", "hex", "impl-serde", - "keccak-hash", + "keccak-hash 0.11.0", "parity-scale-codec", - "primitive-types", + "primitive-types 0.13.1", "scale-bits", "scale-decode", "scale-encode", @@ -5393,7 +5527,7 @@ dependencies = [ "impl-serde", "jsonrpsee", "parity-scale-codec", - "primitive-types", + "primitive-types 0.13.1", "serde", "serde_json", "subxt-core", @@ -5898,6 +6032,18 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "uint" version = "0.10.0" @@ -5953,6 +6099,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "unroll" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 33008d8..8e7b3f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ path = "src/lib.rs" name = "quantus" path = "src/main.rs" - [dependencies] # CLI and async runtime clap = { version = "4.5", features = ["derive"] } @@ -52,9 +51,10 @@ aes-gcm = "0.10" # AES-256-GCM (quantum-safe with 256-bit keys) # Quantus crypto dependencies qp-rusty-crystals-dilithium = { version = "2.0.0" } qp-rusty-crystals-hdwallet = { version = "1.0.0" } -qp-poseidon = { version = "0.9.5", features = [ +qp-poseidon = { version = "1.0.6", features = [ "serde", ] } +qp-poseidon-core = { version = "1.0.6", default-features = false, features = ["p2", "p3"] } qp-dilithium-crypto = { version = "0.2.0", features = ["serde"] } # Blockchain and RPC client @@ -70,5 +70,12 @@ jsonrpsee = { version = "0.24", features = ["client"] } # Needed for implementing custom Subxt hasher subxt-metadata = "0.43.0" +# ZK proof generation +anyhow = "1.0" +qp-wormhole-circuit = { version = "0.1.7", default-features = false } +qp-wormhole-prover = { version = "0.1.7", default-features = false } +qp-zk-circuits-common = { version = "0.1.7", default-features = false } +qp-plonky2 = { version = "1.1.3", default-features = false, features = ["no_random"] } + [dev-dependencies] tempfile = "3.8" diff --git a/src/chain/quantus_subxt.rs b/src/chain/quantus_subxt.rs index a94a0d2..05e2ec8 100644 --- a/src/chain/quantus_subxt.rs +++ b/src/chain/quantus_subxt.rs @@ -6,7 +6,7 @@ pub mod api { mod root_mod { pub use super::*; } - pub static PALLETS: [&str; 22usize] = [ + pub static PALLETS: [&str; 23usize] = [ "System", "Timestamp", "Balances", @@ -29,6 +29,7 @@ pub mod api { "Recovery", "Assets", "AssetsHolder", + "Wormhole", ]; pub static RUNTIME_APIS: [&str; 11usize] = [ "Core", @@ -144,9 +145,10 @@ pub mod api { "execute_block", types::ExecuteBlock { block }, [ - 133u8, 135u8, 228u8, 65u8, 106u8, 27u8, 85u8, 158u8, 112u8, 254u8, - 93u8, 26u8, 102u8, 201u8, 118u8, 216u8, 249u8, 247u8, 91u8, 74u8, 56u8, - 208u8, 231u8, 115u8, 131u8, 29u8, 209u8, 6u8, 65u8, 57u8, 214u8, 125u8, + 81u8, 130u8, 143u8, 72u8, 156u8, 15u8, 28u8, 87u8, 117u8, 10u8, 192u8, + 249u8, 117u8, 214u8, 184u8, 13u8, 148u8, 224u8, 167u8, 170u8, 101u8, + 194u8, 229u8, 140u8, 199u8, 115u8, 73u8, 99u8, 183u8, 205u8, 98u8, + 33u8, ], ) } @@ -163,9 +165,9 @@ pub mod api { "initialize_block", types::InitializeBlock { header }, [ - 132u8, 169u8, 113u8, 112u8, 80u8, 139u8, 113u8, 35u8, 41u8, 81u8, 36u8, - 35u8, 37u8, 202u8, 29u8, 207u8, 205u8, 229u8, 145u8, 7u8, 133u8, 94u8, - 25u8, 108u8, 233u8, 86u8, 234u8, 29u8, 236u8, 57u8, 56u8, 186u8, + 112u8, 139u8, 92u8, 30u8, 37u8, 99u8, 47u8, 83u8, 221u8, 31u8, 204u8, + 129u8, 102u8, 92u8, 144u8, 80u8, 3u8, 98u8, 157u8, 5u8, 20u8, 31u8, + 110u8, 105u8, 86u8, 91u8, 173u8, 19u8, 140u8, 246u8, 60u8, 223u8, ], ) } @@ -193,7 +195,7 @@ pub mod api { pub struct Version {} pub mod execute_block { use super::runtime_types; - pub type Block = runtime_types :: sp_runtime :: generic :: block :: Block < runtime_types :: sp_runtime :: generic :: header :: Header < :: core :: primitive :: u32 > , :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > > ; + pub type Block = runtime_types :: sp_runtime :: generic :: block :: Block < runtime_types :: qp_header :: Header < :: core :: primitive :: u32 > , :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > > ; pub mod output { use super::runtime_types; pub type Output = (); @@ -215,8 +217,7 @@ pub mod api { } pub mod initialize_block { use super::runtime_types; - pub type Header = - runtime_types::sp_runtime::generic::header::Header<::core::primitive::u32>; + pub type Header = runtime_types::qp_header::Header<::core::primitive::u32>; pub mod output { use super::runtime_types; pub type Output = runtime_types::sp_runtime::ExtrinsicInclusionMode; @@ -411,9 +412,9 @@ pub mod api { "finalize_block", types::FinalizeBlock {}, [ - 244u8, 207u8, 24u8, 33u8, 13u8, 69u8, 9u8, 249u8, 145u8, 143u8, 122u8, - 96u8, 197u8, 55u8, 64u8, 111u8, 238u8, 224u8, 34u8, 201u8, 27u8, 146u8, - 232u8, 99u8, 191u8, 30u8, 114u8, 16u8, 32u8, 220u8, 58u8, 62u8, + 135u8, 81u8, 28u8, 123u8, 19u8, 171u8, 129u8, 82u8, 85u8, 96u8, 238u8, + 155u8, 211u8, 153u8, 243u8, 31u8, 189u8, 82u8, 91u8, 225u8, 78u8, 48u8, + 241u8, 236u8, 143u8, 65u8, 91u8, 167u8, 114u8, 146u8, 31u8, 197u8, ], ) } @@ -451,10 +452,10 @@ pub mod api { "check_inherents", types::CheckInherents { block, data }, [ - 153u8, 134u8, 1u8, 215u8, 139u8, 11u8, 53u8, 51u8, 210u8, 175u8, 197u8, - 28u8, 38u8, 209u8, 175u8, 247u8, 142u8, 157u8, 50u8, 151u8, 164u8, - 191u8, 181u8, 118u8, 80u8, 97u8, 160u8, 248u8, 110u8, 217u8, 181u8, - 234u8, + 44u8, 230u8, 134u8, 154u8, 73u8, 173u8, 160u8, 231u8, 223u8, 148u8, + 247u8, 104u8, 214u8, 168u8, 43u8, 202u8, 204u8, 14u8, 148u8, 154u8, + 9u8, 103u8, 239u8, 45u8, 186u8, 21u8, 97u8, 136u8, 200u8, 108u8, 205u8, + 167u8, ], ) } @@ -463,7 +464,7 @@ pub mod api { use super::runtime_types; pub mod apply_extrinsic { use super::runtime_types; - pub type Extrinsic = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > ; + pub type Extrinsic = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > ; pub mod output { use super::runtime_types; pub type Output = :: core :: result :: Result < :: core :: result :: Result < () , runtime_types :: sp_runtime :: DispatchError > , runtime_types :: sp_runtime :: transaction_validity :: TransactionValidityError > ; @@ -487,9 +488,7 @@ pub mod api { use super::runtime_types; pub mod output { use super::runtime_types; - pub type Output = runtime_types::sp_runtime::generic::header::Header< - ::core::primitive::u32, - >; + pub type Output = runtime_types::qp_header::Header<::core::primitive::u32>; } } #[derive( @@ -509,7 +508,7 @@ pub mod api { pub type Inherent = runtime_types::sp_inherents::InherentData; pub mod output { use super::runtime_types; - pub type Output = :: subxt :: ext :: subxt_core :: alloc :: vec :: Vec < :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > > ; + pub type Output = :: subxt :: ext :: subxt_core :: alloc :: vec :: Vec < :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > > ; } } #[derive( @@ -528,7 +527,7 @@ pub mod api { } pub mod check_inherents { use super::runtime_types; - pub type Block = runtime_types :: sp_runtime :: generic :: block :: Block < runtime_types :: sp_runtime :: generic :: header :: Header < :: core :: primitive :: u32 > , :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > > ; + pub type Block = runtime_types :: sp_runtime :: generic :: block :: Block < runtime_types :: qp_header :: Header < :: core :: primitive :: u32 > , :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > > ; pub type Data = runtime_types::sp_inherents::InherentData; pub mod output { use super::runtime_types; @@ -594,7 +593,7 @@ pub mod api { use super::runtime_types; pub type Source = runtime_types::sp_runtime::transaction_validity::TransactionSource; - pub type Tx = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > ; + pub type Tx = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > ; pub type BlockHash = ::subxt::ext::subxt_core::utils::H256; pub mod output { use super::runtime_types; @@ -637,9 +636,10 @@ pub mod api { "offchain_worker", types::OffchainWorker { header }, [ - 10u8, 135u8, 19u8, 153u8, 33u8, 216u8, 18u8, 242u8, 33u8, 140u8, 4u8, - 223u8, 200u8, 130u8, 103u8, 118u8, 137u8, 24u8, 19u8, 127u8, 161u8, - 29u8, 184u8, 111u8, 222u8, 111u8, 253u8, 73u8, 45u8, 31u8, 79u8, 60u8, + 131u8, 199u8, 206u8, 86u8, 209u8, 109u8, 229u8, 152u8, 235u8, 155u8, + 35u8, 252u8, 70u8, 180u8, 47u8, 173u8, 84u8, 182u8, 176u8, 164u8, + 107u8, 88u8, 249u8, 181u8, 85u8, 174u8, 240u8, 226u8, 254u8, 189u8, + 167u8, 155u8, ], ) } @@ -648,8 +648,7 @@ pub mod api { use super::runtime_types; pub mod offchain_worker { use super::runtime_types; - pub type Header = - runtime_types::sp_runtime::generic::header::Header<::core::primitive::u32>; + pub type Header = runtime_types::qp_header::Header<::core::primitive::u32>; pub mod output { use super::runtime_types; pub type Output = (); @@ -1355,7 +1354,7 @@ pub mod api { use super::runtime_types; pub mod query_info { use super::runtime_types; - pub type Uxt = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > ; + pub type Uxt = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > ; pub type Len = ::core::primitive::u32; pub mod output { use super::runtime_types; @@ -1383,7 +1382,7 @@ pub mod api { } pub mod query_fee_details { use super::runtime_types; - pub type Uxt = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension ,) > ; + pub type Uxt = :: subxt :: ext :: subxt_core :: utils :: UncheckedExtrinsic < :: subxt :: ext :: subxt_core :: utils :: MultiAddress < :: subxt :: ext :: subxt_core :: utils :: AccountId32 , () > , runtime_types :: quantus_runtime :: RuntimeCall , runtime_types :: qp_dilithium_crypto :: types :: DilithiumSignatureScheme , (runtime_types :: frame_system :: extensions :: check_non_zero_sender :: CheckNonZeroSender , runtime_types :: frame_system :: extensions :: check_spec_version :: CheckSpecVersion , runtime_types :: frame_system :: extensions :: check_tx_version :: CheckTxVersion , runtime_types :: frame_system :: extensions :: check_genesis :: CheckGenesis , runtime_types :: frame_system :: extensions :: check_mortality :: CheckMortality , runtime_types :: frame_system :: extensions :: check_nonce :: CheckNonce , runtime_types :: frame_system :: extensions :: check_weight :: CheckWeight , runtime_types :: pallet_transaction_payment :: ChargeTransactionPayment , runtime_types :: frame_metadata_hash_extension :: CheckMetadataHash , runtime_types :: quantus_runtime :: transaction_extensions :: ReversibleTransactionExtension , runtime_types :: quantus_runtime :: transaction_extensions :: WormholeProofRecorderExtension ,) > ; pub type Len = ::core::primitive::u32; pub mod output { use super::runtime_types; @@ -1472,10 +1471,9 @@ pub mod api { "query_call_info", types::QueryCallInfo { call, len }, [ - 166u8, 173u8, 176u8, 212u8, 240u8, 248u8, 215u8, 188u8, 215u8, 21u8, - 209u8, 116u8, 183u8, 186u8, 201u8, 229u8, 28u8, 26u8, 218u8, 247u8, - 99u8, 59u8, 155u8, 235u8, 205u8, 76u8, 165u8, 181u8, 148u8, 21u8, - 122u8, 86u8, + 144u8, 69u8, 76u8, 20u8, 225u8, 168u8, 95u8, 163u8, 136u8, 202u8, 72u8, + 27u8, 234u8, 2u8, 87u8, 1u8, 106u8, 223u8, 192u8, 30u8, 20u8, 233u8, + 167u8, 128u8, 112u8, 225u8, 153u8, 125u8, 248u8, 228u8, 53u8, 167u8, ], ) } @@ -1493,9 +1491,10 @@ pub mod api { "query_call_fee_details", types::QueryCallFeeDetails { call, len }, [ - 18u8, 80u8, 212u8, 196u8, 230u8, 162u8, 108u8, 100u8, 130u8, 14u8, - 44u8, 76u8, 26u8, 143u8, 202u8, 61u8, 26u8, 132u8, 34u8, 112u8, 49u8, - 183u8, 31u8, 51u8, 122u8, 49u8, 37u8, 229u8, 87u8, 43u8, 107u8, 82u8, + 86u8, 238u8, 23u8, 213u8, 191u8, 145u8, 151u8, 110u8, 183u8, 238u8, + 148u8, 145u8, 134u8, 41u8, 240u8, 193u8, 187u8, 232u8, 19u8, 217u8, + 179u8, 188u8, 8u8, 191u8, 23u8, 18u8, 155u8, 52u8, 12u8, 169u8, 221u8, + 101u8, ], ) } @@ -1868,6 +1867,9 @@ pub mod api { pub fn assets(&self) -> assets::constants::ConstantsApi { assets::constants::ConstantsApi } + pub fn wormhole(&self) -> wormhole::constants::ConstantsApi { + wormhole::constants::ConstantsApi + } } pub struct StorageApi; impl StorageApi { @@ -1931,6 +1933,9 @@ pub mod api { pub fn assets_holder(&self) -> assets_holder::storage::StorageApi { assets_holder::storage::StorageApi } + pub fn wormhole(&self) -> wormhole::storage::StorageApi { + wormhole::storage::StorageApi + } } pub struct TransactionApi; impl TransactionApi { @@ -1985,6 +1990,9 @@ pub mod api { pub fn assets(&self) -> assets::calls::TransactionApi { assets::calls::TransactionApi } + pub fn wormhole(&self) -> wormhole::calls::TransactionApi { + wormhole::calls::TransactionApi + } } pub struct ViewFunctionsApi; impl ViewFunctionsApi {} @@ -1997,9 +2005,9 @@ pub mod api { .hash(); runtime_metadata_hash == [ - 194u8, 46u8, 30u8, 103u8, 67u8, 25u8, 224u8, 42u8, 104u8, 224u8, 105u8, 213u8, - 149u8, 58u8, 199u8, 151u8, 221u8, 215u8, 141u8, 247u8, 109u8, 85u8, 204u8, 202u8, - 96u8, 104u8, 173u8, 94u8, 198u8, 124u8, 113u8, 174u8, + 188u8, 39u8, 127u8, 207u8, 32u8, 174u8, 40u8, 37u8, 8u8, 103u8, 134u8, 90u8, 25u8, + 13u8, 113u8, 231u8, 42u8, 35u8, 1u8, 219u8, 62u8, 142u8, 175u8, 90u8, 219u8, 204u8, + 82u8, 53u8, 187u8, 156u8, 226u8, 105u8, ] } pub mod system { @@ -3098,10 +3106,10 @@ pub mod api { "Events", (), [ - 153u8, 144u8, 222u8, 32u8, 219u8, 80u8, 161u8, 232u8, 120u8, 168u8, - 102u8, 147u8, 49u8, 48u8, 3u8, 26u8, 255u8, 126u8, 218u8, 117u8, 254u8, - 217u8, 170u8, 206u8, 182u8, 174u8, 251u8, 53u8, 253u8, 242u8, 26u8, - 74u8, + 233u8, 203u8, 207u8, 158u8, 57u8, 161u8, 88u8, 160u8, 148u8, 0u8, + 176u8, 254u8, 251u8, 206u8, 46u8, 94u8, 178u8, 136u8, 154u8, 109u8, + 197u8, 147u8, 125u8, 17u8, 120u8, 246u8, 69u8, 50u8, 48u8, 172u8, 81u8, + 34u8, ], ) } @@ -4675,20 +4683,6 @@ pub mod api { >; pub type Param0 = ::subxt::ext::subxt_core::utils::AccountId32; } - pub mod transfer_proof { - use super::runtime_types; - pub type TransferProof = (); - pub type Param0 = ( - ::core::primitive::u64, - ::subxt::ext::subxt_core::utils::AccountId32, - ::subxt::ext::subxt_core::utils::AccountId32, - ::core::primitive::u128, - ); - } - pub mod transfer_count { - use super::runtime_types; - pub type TransferCount = ::core::primitive::u64; - } } pub struct StorageApi; impl StorageApi { @@ -5016,74 +5010,6 @@ pub mod api { ], ) } - #[doc = " Transfer proofs for a wormhole transfers"] - pub fn transfer_proof_iter( - &self, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - (), - types::transfer_proof::TransferProof, - (), - (), - ::subxt::ext::subxt_core::utils::Yes, - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "Balances", - "TransferProof", - (), - [ - 210u8, 54u8, 36u8, 79u8, 12u8, 123u8, 227u8, 172u8, 23u8, 232u8, 200u8, - 138u8, 130u8, 99u8, 12u8, 186u8, 77u8, 74u8, 208u8, 111u8, 137u8, - 159u8, 169u8, 112u8, 227u8, 111u8, 65u8, 127u8, 232u8, 57u8, 166u8, - 14u8, - ], - ) - } - #[doc = " Transfer proofs for a wormhole transfers"] - pub fn transfer_proof( - &self, - _0: types::transfer_proof::Param0, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - ::subxt::ext::subxt_core::storage::address::StaticStorageKey< - types::transfer_proof::Param0, - >, - types::transfer_proof::TransferProof, - ::subxt::ext::subxt_core::utils::Yes, - (), - (), - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "Balances", - "TransferProof", - ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), - [ - 210u8, 54u8, 36u8, 79u8, 12u8, 123u8, 227u8, 172u8, 23u8, 232u8, 200u8, - 138u8, 130u8, 99u8, 12u8, 186u8, 77u8, 74u8, 208u8, 111u8, 137u8, - 159u8, 169u8, 112u8, 227u8, 111u8, 65u8, 127u8, 232u8, 57u8, 166u8, - 14u8, - ], - ) - } - pub fn transfer_count( - &self, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - (), - types::transfer_count::TransferCount, - ::subxt::ext::subxt_core::utils::Yes, - ::subxt::ext::subxt_core::utils::Yes, - (), - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "Balances", - "TransferCount", - (), - [ - 105u8, 10u8, 160u8, 118u8, 193u8, 131u8, 207u8, 188u8, 78u8, 238u8, - 252u8, 99u8, 31u8, 72u8, 159u8, 128u8, 159u8, 215u8, 110u8, 101u8, - 27u8, 132u8, 12u8, 59u8, 182u8, 107u8, 98u8, 77u8, 189u8, 100u8, 51u8, - 209u8, - ], - ) - } } } pub mod constants { @@ -5463,9 +5389,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 35u8, 97u8, 151u8, 80u8, 160u8, 5u8, 249u8, 161u8, 124u8, 31u8, 46u8, - 45u8, 205u8, 88u8, 85u8, 115u8, 98u8, 172u8, 229u8, 119u8, 45u8, 74u8, - 176u8, 35u8, 216u8, 58u8, 23u8, 103u8, 209u8, 201u8, 15u8, 61u8, + 168u8, 100u8, 48u8, 116u8, 163u8, 192u8, 242u8, 52u8, 119u8, 87u8, + 194u8, 233u8, 96u8, 99u8, 148u8, 199u8, 189u8, 152u8, 42u8, 69u8, + 195u8, 93u8, 2u8, 53u8, 139u8, 85u8, 19u8, 63u8, 251u8, 30u8, 244u8, + 30u8, ], ) } @@ -5488,10 +5415,10 @@ pub mod api { weight, }, [ - 129u8, 254u8, 188u8, 113u8, 132u8, 176u8, 63u8, 138u8, 200u8, 84u8, - 62u8, 198u8, 140u8, 161u8, 52u8, 222u8, 184u8, 140u8, 204u8, 144u8, - 247u8, 118u8, 46u8, 126u8, 211u8, 117u8, 140u8, 227u8, 105u8, 74u8, - 162u8, 225u8, + 181u8, 252u8, 48u8, 252u8, 226u8, 4u8, 157u8, 205u8, 114u8, 223u8, + 86u8, 149u8, 228u8, 170u8, 164u8, 255u8, 152u8, 191u8, 239u8, 205u8, + 149u8, 126u8, 209u8, 188u8, 197u8, 250u8, 24u8, 208u8, 212u8, 168u8, + 66u8, 131u8, ], ) } @@ -5529,10 +5456,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 174u8, 114u8, 45u8, 150u8, 219u8, 165u8, 118u8, 166u8, 250u8, 85u8, - 15u8, 165u8, 148u8, 17u8, 160u8, 123u8, 198u8, 241u8, 78u8, 198u8, - 206u8, 131u8, 9u8, 107u8, 172u8, 188u8, 83u8, 6u8, 234u8, 14u8, 211u8, - 76u8, + 158u8, 186u8, 229u8, 16u8, 76u8, 224u8, 81u8, 198u8, 111u8, 234u8, + 112u8, 64u8, 248u8, 191u8, 138u8, 69u8, 111u8, 215u8, 204u8, 69u8, + 43u8, 60u8, 173u8, 141u8, 200u8, 113u8, 143u8, 75u8, 33u8, 84u8, 108u8, + 149u8, ], ) } @@ -7610,10 +7537,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 171u8, 151u8, 176u8, 198u8, 154u8, 6u8, 181u8, 56u8, 10u8, 6u8, 38u8, - 136u8, 64u8, 214u8, 145u8, 96u8, 121u8, 125u8, 161u8, 234u8, 247u8, - 156u8, 152u8, 119u8, 122u8, 165u8, 125u8, 238u8, 12u8, 214u8, 135u8, - 21u8, + 98u8, 56u8, 162u8, 148u8, 112u8, 249u8, 195u8, 138u8, 14u8, 208u8, + 216u8, 29u8, 136u8, 77u8, 22u8, 170u8, 181u8, 92u8, 215u8, 105u8, + 123u8, 64u8, 0u8, 48u8, 135u8, 65u8, 103u8, 121u8, 222u8, 161u8, 220u8, + 252u8, ], ) } @@ -7655,9 +7582,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 99u8, 222u8, 117u8, 153u8, 121u8, 239u8, 26u8, 216u8, 66u8, 132u8, - 220u8, 8u8, 92u8, 137u8, 253u8, 47u8, 9u8, 8u8, 103u8, 1u8, 116u8, - 133u8, 237u8, 51u8, 73u8, 145u8, 141u8, 64u8, 210u8, 10u8, 74u8, 191u8, + 199u8, 176u8, 11u8, 253u8, 206u8, 181u8, 22u8, 109u8, 121u8, 2u8, + 189u8, 149u8, 188u8, 210u8, 81u8, 219u8, 147u8, 140u8, 252u8, 149u8, + 128u8, 248u8, 171u8, 106u8, 7u8, 152u8, 32u8, 65u8, 61u8, 121u8, 175u8, + 153u8, ], ) } @@ -7696,10 +7624,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 236u8, 32u8, 229u8, 48u8, 43u8, 173u8, 230u8, 106u8, 109u8, 188u8, - 137u8, 151u8, 188u8, 102u8, 252u8, 210u8, 87u8, 146u8, 152u8, 251u8, - 128u8, 10u8, 230u8, 228u8, 168u8, 203u8, 77u8, 24u8, 125u8, 18u8, 52u8, - 201u8, + 241u8, 149u8, 155u8, 185u8, 58u8, 107u8, 11u8, 188u8, 177u8, 36u8, + 106u8, 40u8, 178u8, 137u8, 85u8, 190u8, 46u8, 56u8, 244u8, 20u8, 150u8, + 238u8, 73u8, 111u8, 151u8, 150u8, 2u8, 133u8, 218u8, 189u8, 95u8, + 109u8, ], ) } @@ -7724,9 +7652,9 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 120u8, 118u8, 201u8, 138u8, 43u8, 75u8, 89u8, 65u8, 107u8, 106u8, 41u8, - 229u8, 55u8, 6u8, 141u8, 24u8, 116u8, 214u8, 215u8, 1u8, 209u8, 67u8, - 157u8, 238u8, 147u8, 31u8, 188u8, 133u8, 21u8, 7u8, 199u8, 202u8, + 130u8, 87u8, 248u8, 189u8, 84u8, 139u8, 26u8, 139u8, 35u8, 18u8, 102u8, + 95u8, 127u8, 218u8, 144u8, 149u8, 65u8, 134u8, 86u8, 98u8, 195u8, + 192u8, 79u8, 154u8, 7u8, 232u8, 76u8, 179u8, 255u8, 188u8, 29u8, 191u8, ], ) } @@ -8754,10 +8682,9 @@ pub mod api { "batch", types::Batch { calls }, [ - 135u8, 106u8, 152u8, 39u8, 199u8, 163u8, 145u8, 186u8, 129u8, 115u8, - 214u8, 162u8, 12u8, 85u8, 57u8, 122u8, 211u8, 240u8, 143u8, 159u8, - 138u8, 37u8, 114u8, 8u8, 8u8, 236u8, 197u8, 23u8, 114u8, 2u8, 105u8, - 174u8, + 143u8, 230u8, 160u8, 33u8, 51u8, 78u8, 98u8, 70u8, 24u8, 252u8, 53u8, + 95u8, 142u8, 254u8, 85u8, 220u8, 208u8, 135u8, 35u8, 223u8, 159u8, 9u8, + 252u8, 220u8, 43u8, 167u8, 49u8, 44u8, 89u8, 178u8, 227u8, 192u8, ], ) } @@ -8787,9 +8714,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 3u8, 102u8, 237u8, 140u8, 8u8, 207u8, 27u8, 204u8, 155u8, 162u8, 124u8, - 141u8, 172u8, 210u8, 89u8, 239u8, 113u8, 175u8, 41u8, 9u8, 150u8, - 130u8, 205u8, 125u8, 205u8, 199u8, 174u8, 85u8, 24u8, 13u8, 57u8, 19u8, + 214u8, 237u8, 32u8, 195u8, 191u8, 195u8, 55u8, 60u8, 99u8, 181u8, + 242u8, 109u8, 51u8, 83u8, 103u8, 100u8, 4u8, 196u8, 130u8, 130u8, + 190u8, 179u8, 224u8, 200u8, 67u8, 61u8, 214u8, 118u8, 5u8, 91u8, 104u8, + 72u8, ], ) } @@ -8815,9 +8743,9 @@ pub mod api { "batch_all", types::BatchAll { calls }, [ - 76u8, 242u8, 205u8, 32u8, 158u8, 24u8, 255u8, 12u8, 97u8, 24u8, 211u8, - 63u8, 119u8, 183u8, 165u8, 217u8, 17u8, 178u8, 254u8, 230u8, 119u8, - 207u8, 207u8, 103u8, 39u8, 226u8, 55u8, 73u8, 233u8, 79u8, 60u8, 218u8, + 181u8, 57u8, 166u8, 110u8, 27u8, 199u8, 129u8, 206u8, 52u8, 238u8, + 32u8, 165u8, 37u8, 48u8, 103u8, 144u8, 138u8, 34u8, 41u8, 94u8, 246u8, + 41u8, 110u8, 214u8, 14u8, 114u8, 86u8, 44u8, 95u8, 14u8, 201u8, 175u8, ], ) } @@ -8840,10 +8768,9 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 32u8, 108u8, 91u8, 136u8, 200u8, 228u8, 95u8, 44u8, 22u8, 92u8, 34u8, - 234u8, 170u8, 201u8, 4u8, 248u8, 16u8, 209u8, 103u8, 201u8, 207u8, - 160u8, 165u8, 231u8, 152u8, 222u8, 112u8, 63u8, 133u8, 61u8, 220u8, - 24u8, + 10u8, 157u8, 57u8, 66u8, 109u8, 65u8, 72u8, 193u8, 5u8, 242u8, 129u8, + 169u8, 57u8, 0u8, 3u8, 210u8, 146u8, 49u8, 26u8, 109u8, 117u8, 2u8, + 189u8, 69u8, 186u8, 28u8, 163u8, 235u8, 225u8, 210u8, 111u8, 177u8, ], ) } @@ -8869,9 +8796,9 @@ pub mod api { "force_batch", types::ForceBatch { calls }, [ - 26u8, 82u8, 61u8, 185u8, 19u8, 29u8, 151u8, 192u8, 24u8, 41u8, 115u8, - 237u8, 7u8, 38u8, 68u8, 5u8, 159u8, 117u8, 47u8, 138u8, 101u8, 126u8, - 255u8, 137u8, 144u8, 51u8, 244u8, 145u8, 113u8, 21u8, 123u8, 79u8, + 236u8, 54u8, 180u8, 85u8, 81u8, 119u8, 70u8, 224u8, 73u8, 103u8, 169u8, + 41u8, 191u8, 56u8, 138u8, 114u8, 255u8, 207u8, 13u8, 219u8, 217u8, + 35u8, 131u8, 51u8, 220u8, 168u8, 191u8, 5u8, 98u8, 225u8, 50u8, 137u8, ], ) } @@ -8894,10 +8821,10 @@ pub mod api { weight, }, [ - 131u8, 134u8, 250u8, 73u8, 141u8, 137u8, 137u8, 15u8, 206u8, 215u8, - 199u8, 239u8, 24u8, 84u8, 247u8, 50u8, 135u8, 223u8, 110u8, 205u8, - 96u8, 170u8, 74u8, 232u8, 152u8, 135u8, 235u8, 62u8, 110u8, 230u8, - 172u8, 229u8, + 253u8, 207u8, 162u8, 133u8, 214u8, 66u8, 111u8, 171u8, 181u8, 86u8, + 82u8, 24u8, 121u8, 127u8, 80u8, 92u8, 21u8, 81u8, 255u8, 176u8, 61u8, + 95u8, 195u8, 109u8, 197u8, 42u8, 54u8, 204u8, 148u8, 107u8, 212u8, + 236u8, ], ) } @@ -8937,10 +8864,9 @@ pub mod api { fallback: ::subxt::ext::subxt_core::alloc::boxed::Box::new(fallback), }, [ - 195u8, 146u8, 198u8, 20u8, 96u8, 236u8, 218u8, 101u8, 252u8, 17u8, - 41u8, 246u8, 142u8, 116u8, 243u8, 198u8, 237u8, 168u8, 11u8, 211u8, - 236u8, 184u8, 71u8, 173u8, 211u8, 0u8, 129u8, 231u8, 99u8, 189u8, - 229u8, 34u8, + 251u8, 49u8, 108u8, 91u8, 215u8, 66u8, 153u8, 50u8, 76u8, 22u8, 82u8, + 115u8, 88u8, 37u8, 50u8, 69u8, 92u8, 225u8, 34u8, 143u8, 59u8, 13u8, + 222u8, 29u8, 130u8, 66u8, 25u8, 162u8, 78u8, 5u8, 113u8, 244u8, ], ) } @@ -8963,9 +8889,9 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 52u8, 4u8, 122u8, 93u8, 231u8, 186u8, 88u8, 129u8, 36u8, 245u8, 176u8, - 117u8, 22u8, 203u8, 94u8, 115u8, 19u8, 27u8, 141u8, 63u8, 184u8, 171u8, - 146u8, 63u8, 124u8, 225u8, 135u8, 73u8, 51u8, 20u8, 60u8, 199u8, + 20u8, 7u8, 177u8, 85u8, 1u8, 244u8, 203u8, 254u8, 2u8, 41u8, 209u8, + 209u8, 100u8, 23u8, 237u8, 67u8, 162u8, 62u8, 226u8, 220u8, 77u8, + 112u8, 238u8, 124u8, 247u8, 247u8, 153u8, 8u8, 19u8, 82u8, 84u8, 163u8, ], ) } @@ -16571,10 +16497,9 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 60u8, 61u8, 138u8, 19u8, 43u8, 218u8, 179u8, 117u8, 205u8, 143u8, - 128u8, 223u8, 96u8, 166u8, 90u8, 187u8, 255u8, 119u8, 238u8, 209u8, - 140u8, 58u8, 239u8, 44u8, 153u8, 196u8, 218u8, 155u8, 227u8, 228u8, - 210u8, 187u8, + 62u8, 111u8, 80u8, 232u8, 188u8, 15u8, 202u8, 50u8, 77u8, 223u8, 96u8, + 15u8, 232u8, 213u8, 143u8, 185u8, 200u8, 40u8, 119u8, 120u8, 195u8, + 183u8, 193u8, 129u8, 198u8, 43u8, 220u8, 26u8, 149u8, 14u8, 92u8, 42u8, ], ) } @@ -21110,6 +21035,442 @@ pub mod api { } } } + pub mod wormhole { + use super::{root_mod, runtime_types}; + #[doc = "The `Error` enum of this pallet."] + pub type Error = runtime_types::pallet_wormhole::pallet::Error; + #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] + pub type Call = runtime_types::pallet_wormhole::pallet::Call; + pub mod calls { + use super::{root_mod, runtime_types}; + type DispatchError = runtime_types::sp_runtime::DispatchError; + pub mod types { + use super::runtime_types; + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + pub struct VerifyWormholeProof { + pub proof_bytes: verify_wormhole_proof::ProofBytes, + } + pub mod verify_wormhole_proof { + use super::runtime_types; + pub type ProofBytes = + ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>; + } + impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for VerifyWormholeProof { + const PALLET: &'static str = "Wormhole"; + const CALL: &'static str = "verify_wormhole_proof"; + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "Transfer native tokens and store proof for wormhole"] + pub struct TransferNative { + pub dest: transfer_native::Dest, + #[codec(compact)] + pub amount: transfer_native::Amount, + } + pub mod transfer_native { + use super::runtime_types; + pub type Dest = ::subxt::ext::subxt_core::utils::MultiAddress< + ::subxt::ext::subxt_core::utils::AccountId32, + (), + >; + pub type Amount = ::core::primitive::u128; + } + impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for TransferNative { + const PALLET: &'static str = "Wormhole"; + const CALL: &'static str = "transfer_native"; + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "Transfer asset tokens and store proof for wormhole"] + pub struct TransferAsset { + pub asset_id: transfer_asset::AssetId, + pub dest: transfer_asset::Dest, + #[codec(compact)] + pub amount: transfer_asset::Amount, + } + pub mod transfer_asset { + use super::runtime_types; + pub type AssetId = ::core::primitive::u32; + pub type Dest = ::subxt::ext::subxt_core::utils::MultiAddress< + ::subxt::ext::subxt_core::utils::AccountId32, + (), + >; + pub type Amount = ::core::primitive::u128; + } + impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for TransferAsset { + const PALLET: &'static str = "Wormhole"; + const CALL: &'static str = "transfer_asset"; + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "Verify an aggregated wormhole proof and process all transfers in the batch"] + pub struct VerifyAggregatedProof { + pub proof_bytes: verify_aggregated_proof::ProofBytes, + } + pub mod verify_aggregated_proof { + use super::runtime_types; + pub type ProofBytes = + ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>; + } + impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for VerifyAggregatedProof { + const PALLET: &'static str = "Wormhole"; + const CALL: &'static str = "verify_aggregated_proof"; + } + } + pub struct TransactionApi; + impl TransactionApi { + pub fn verify_wormhole_proof( + &self, + proof_bytes: types::verify_wormhole_proof::ProofBytes, + ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload + { + ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( + "Wormhole", + "verify_wormhole_proof", + types::VerifyWormholeProof { proof_bytes }, + [ + 242u8, 232u8, 238u8, 253u8, 96u8, 217u8, 86u8, 251u8, 216u8, 200u8, + 103u8, 7u8, 182u8, 218u8, 118u8, 149u8, 120u8, 244u8, 124u8, 33u8, + 133u8, 50u8, 150u8, 163u8, 187u8, 19u8, 37u8, 76u8, 73u8, 48u8, 213u8, + 193u8, + ], + ) + } + #[doc = "Transfer native tokens and store proof for wormhole"] + pub fn transfer_native( + &self, + dest: types::transfer_native::Dest, + amount: types::transfer_native::Amount, + ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload + { + ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( + "Wormhole", + "transfer_native", + types::TransferNative { dest, amount }, + [ + 108u8, 65u8, 158u8, 226u8, 204u8, 38u8, 41u8, 193u8, 72u8, 15u8, 175u8, + 111u8, 213u8, 47u8, 70u8, 113u8, 235u8, 77u8, 160u8, 118u8, 210u8, + 134u8, 44u8, 76u8, 24u8, 231u8, 234u8, 50u8, 44u8, 75u8, 99u8, 215u8, + ], + ) + } + #[doc = "Transfer asset tokens and store proof for wormhole"] + pub fn transfer_asset( + &self, + asset_id: types::transfer_asset::AssetId, + dest: types::transfer_asset::Dest, + amount: types::transfer_asset::Amount, + ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload + { + ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( + "Wormhole", + "transfer_asset", + types::TransferAsset { asset_id, dest, amount }, + [ + 49u8, 152u8, 37u8, 165u8, 177u8, 50u8, 177u8, 190u8, 98u8, 23u8, 130u8, + 61u8, 91u8, 175u8, 20u8, 208u8, 21u8, 95u8, 21u8, 10u8, 229u8, 132u8, + 118u8, 155u8, 74u8, 212u8, 103u8, 247u8, 138u8, 49u8, 157u8, 214u8, + ], + ) + } + #[doc = "Verify an aggregated wormhole proof and process all transfers in the batch"] + pub fn verify_aggregated_proof( + &self, + proof_bytes: types::verify_aggregated_proof::ProofBytes, + ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload< + types::VerifyAggregatedProof, + > { + ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( + "Wormhole", + "verify_aggregated_proof", + types::VerifyAggregatedProof { proof_bytes }, + [ + 122u8, 42u8, 194u8, 153u8, 22u8, 66u8, 199u8, 173u8, 19u8, 107u8, + 232u8, 147u8, 77u8, 40u8, 115u8, 208u8, 183u8, 77u8, 46u8, 149u8, 56u8, + 225u8, 146u8, 168u8, 49u8, 248u8, 42u8, 195u8, 180u8, 91u8, 75u8, + 102u8, + ], + ) + } + } + } + #[doc = "The `Event` enum of this pallet"] + pub type Event = runtime_types::pallet_wormhole::pallet::Event; + pub mod events { + use super::runtime_types; + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode")] + pub struct NativeTransferred { + pub from: native_transferred::From, + pub to: native_transferred::To, + pub amount: native_transferred::Amount, + pub transfer_count: native_transferred::TransferCount, + } + pub mod native_transferred { + use super::runtime_types; + pub type From = ::subxt::ext::subxt_core::utils::AccountId32; + pub type To = ::subxt::ext::subxt_core::utils::AccountId32; + pub type Amount = ::core::primitive::u128; + pub type TransferCount = ::core::primitive::u64; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for NativeTransferred { + const PALLET: &'static str = "Wormhole"; + const EVENT: &'static str = "NativeTransferred"; + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode")] + pub struct AssetTransferred { + pub asset_id: asset_transferred::AssetId, + pub from: asset_transferred::From, + pub to: asset_transferred::To, + pub amount: asset_transferred::Amount, + pub transfer_count: asset_transferred::TransferCount, + } + pub mod asset_transferred { + use super::runtime_types; + pub type AssetId = ::core::primitive::u32; + pub type From = ::subxt::ext::subxt_core::utils::AccountId32; + pub type To = ::subxt::ext::subxt_core::utils::AccountId32; + pub type Amount = ::core::primitive::u128; + pub type TransferCount = ::core::primitive::u64; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for AssetTransferred { + const PALLET: &'static str = "Wormhole"; + const EVENT: &'static str = "AssetTransferred"; + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode")] + pub struct ProofVerified { + pub exit_amount: proof_verified::ExitAmount, + } + pub mod proof_verified { + use super::runtime_types; + pub type ExitAmount = ::core::primitive::u128; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for ProofVerified { + const PALLET: &'static str = "Wormhole"; + const EVENT: &'static str = "ProofVerified"; + } + } + pub mod storage { + use super::runtime_types; + pub mod types { + use super::runtime_types; + pub mod used_nullifiers { + use super::runtime_types; + pub type UsedNullifiers = ::core::primitive::bool; + pub type Param0 = [::core::primitive::u8; 32usize]; + } + pub mod transfer_proof { + use super::runtime_types; + pub type TransferProof = (); + pub type Param0 = ( + ::core::primitive::u32, + ::core::primitive::u64, + ::subxt::ext::subxt_core::utils::AccountId32, + ::subxt::ext::subxt_core::utils::AccountId32, + ::core::primitive::u128, + ); + } + pub mod transfer_count { + use super::runtime_types; + pub type TransferCount = ::core::primitive::u64; + } + } + pub struct StorageApi; + impl StorageApi { + pub fn used_nullifiers_iter( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::used_nullifiers::UsedNullifiers, + (), + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "Wormhole", + "UsedNullifiers", + (), + [ + 111u8, 222u8, 249u8, 87u8, 31u8, 249u8, 120u8, 32u8, 221u8, 33u8, 86u8, + 103u8, 116u8, 235u8, 16u8, 191u8, 73u8, 183u8, 183u8, 77u8, 229u8, + 255u8, 221u8, 186u8, 29u8, 179u8, 110u8, 138u8, 146u8, 113u8, 241u8, + 222u8, + ], + ) + } + pub fn used_nullifiers( + &self, + _0: types::used_nullifiers::Param0, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + ::subxt::ext::subxt_core::storage::address::StaticStorageKey< + types::used_nullifiers::Param0, + >, + types::used_nullifiers::UsedNullifiers, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "Wormhole", + "UsedNullifiers", + ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), + [ + 111u8, 222u8, 249u8, 87u8, 31u8, 249u8, 120u8, 32u8, 221u8, 33u8, 86u8, + 103u8, 116u8, 235u8, 16u8, 191u8, 73u8, 183u8, 183u8, 77u8, 229u8, + 255u8, 221u8, 186u8, 29u8, 179u8, 110u8, 138u8, 146u8, 113u8, 241u8, + 222u8, + ], + ) + } + #[doc = " Transfer proofs for wormhole transfers (both native and assets)"] + pub fn transfer_proof_iter( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::transfer_proof::TransferProof, + (), + (), + ::subxt::ext::subxt_core::utils::Yes, + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "Wormhole", + "TransferProof", + (), + [ + 114u8, 93u8, 194u8, 180u8, 234u8, 160u8, 121u8, 23u8, 201u8, 229u8, + 249u8, 211u8, 159u8, 188u8, 127u8, 128u8, 32u8, 26u8, 209u8, 25u8, + 176u8, 192u8, 221u8, 140u8, 46u8, 26u8, 47u8, 223u8, 210u8, 37u8, + 137u8, 90u8, + ], + ) + } + #[doc = " Transfer proofs for wormhole transfers (both native and assets)"] + pub fn transfer_proof( + &self, + _0: types::transfer_proof::Param0, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + ::subxt::ext::subxt_core::storage::address::StaticStorageKey< + types::transfer_proof::Param0, + >, + types::transfer_proof::TransferProof, + ::subxt::ext::subxt_core::utils::Yes, + (), + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "Wormhole", + "TransferProof", + ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), + [ + 114u8, 93u8, 194u8, 180u8, 234u8, 160u8, 121u8, 23u8, 201u8, 229u8, + 249u8, 211u8, 159u8, 188u8, 127u8, 128u8, 32u8, 26u8, 209u8, 25u8, + 176u8, 192u8, 221u8, 140u8, 46u8, 26u8, 47u8, 223u8, 210u8, 37u8, + 137u8, 90u8, + ], + ) + } + #[doc = " Transfer count for all wormhole transfers"] + pub fn transfer_count( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::transfer_count::TransferCount, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "Wormhole", + "TransferCount", + (), + [ + 105u8, 10u8, 160u8, 118u8, 193u8, 131u8, 207u8, 188u8, 78u8, 238u8, + 252u8, 99u8, 31u8, 72u8, 159u8, 128u8, 159u8, 215u8, 110u8, 101u8, + 27u8, 132u8, 12u8, 59u8, 182u8, 107u8, 98u8, 77u8, 189u8, 100u8, 51u8, + 209u8, + ], + ) + } + } + } + pub mod constants { + use super::runtime_types; + pub struct ConstantsApi; + impl ConstantsApi { + #[doc = " Account ID used as the \"from\" account when creating transfer proofs for minted tokens"] + pub fn minting_account( + &self, + ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< + ::subxt::ext::subxt_core::utils::AccountId32, + > { + ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( + "Wormhole", + "MintingAccount", + [ + 115u8, 233u8, 13u8, 223u8, 88u8, 20u8, 202u8, 139u8, 153u8, 28u8, + 155u8, 157u8, 224u8, 66u8, 3u8, 250u8, 23u8, 53u8, 88u8, 168u8, 211u8, + 204u8, 122u8, 166u8, 248u8, 23u8, 174u8, 225u8, 99u8, 108u8, 89u8, + 135u8, + ], + ) + } + } + } + } pub mod runtime_types { use super::runtime_types; pub mod bounded_collections { @@ -27239,6 +27600,135 @@ pub mod api { V1, } } + pub mod pallet_wormhole { + use super::runtime_types; + pub mod pallet { + use super::runtime_types; + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] + pub enum Call { + #[codec(index = 0)] + verify_wormhole_proof { + proof_bytes: + ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + }, + #[codec(index = 1)] + #[doc = "Transfer native tokens and store proof for wormhole"] + transfer_native { + dest: ::subxt::ext::subxt_core::utils::MultiAddress< + ::subxt::ext::subxt_core::utils::AccountId32, + (), + >, + #[codec(compact)] + amount: ::core::primitive::u128, + }, + #[codec(index = 2)] + #[doc = "Transfer asset tokens and store proof for wormhole"] + transfer_asset { + asset_id: ::core::primitive::u32, + dest: ::subxt::ext::subxt_core::utils::MultiAddress< + ::subxt::ext::subxt_core::utils::AccountId32, + (), + >, + #[codec(compact)] + amount: ::core::primitive::u128, + }, + #[codec(index = 3)] + #[doc = "Verify an aggregated wormhole proof and process all transfers in the batch"] + verify_aggregated_proof { + proof_bytes: + ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + }, + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "The `Error` enum of this pallet."] + pub enum Error { + #[codec(index = 0)] + InvalidProof, + #[codec(index = 1)] + ProofDeserializationFailed, + #[codec(index = 2)] + VerificationFailed, + #[codec(index = 3)] + InvalidPublicInputs, + #[codec(index = 4)] + NullifierAlreadyUsed, + #[codec(index = 5)] + VerifierNotAvailable, + #[codec(index = 6)] + InvalidStorageRoot, + #[codec(index = 7)] + StorageRootMismatch, + #[codec(index = 8)] + BlockNotFound, + #[codec(index = 9)] + InvalidBlockNumber, + #[codec(index = 10)] + AssetNotFound, + #[codec(index = 11)] + SelfTransfer, + #[codec(index = 12)] + AggregatedVerifierNotAvailable, + #[codec(index = 13)] + AggregatedProofDeserializationFailed, + #[codec(index = 14)] + AggregatedVerificationFailed, + #[codec(index = 15)] + InvalidAggregatedPublicInputs, + } + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + #[doc = "The `Event` enum of this pallet"] + pub enum Event { + #[codec(index = 0)] + NativeTransferred { + from: ::subxt::ext::subxt_core::utils::AccountId32, + to: ::subxt::ext::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + transfer_count: ::core::primitive::u64, + }, + #[codec(index = 1)] + AssetTransferred { + asset_id: ::core::primitive::u32, + from: ::subxt::ext::subxt_core::utils::AccountId32, + to: ::subxt::ext::subxt_core::utils::AccountId32, + amount: ::core::primitive::u128, + transfer_count: ::core::primitive::u64, + }, + #[codec(index = 2)] + ProofVerified { exit_amount: ::core::primitive::u128 }, + } + } + } pub mod primitive_types { use super::runtime_types; #[derive( @@ -27287,6 +27777,23 @@ pub mod api { } } } + pub mod qp_header { + use super::runtime_types; + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode")] + #[encode_as_type(crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode")] + pub struct Header<_0> { + pub parent_hash: ::subxt::ext::subxt_core::utils::H256, + pub number: _0, + pub state_root: ::subxt::ext::subxt_core::utils::H256, + pub extrinsics_root: ::subxt::ext::subxt_core::utils::H256, + pub digest: runtime_types::sp_runtime::generic::digest::Digest, + } + } pub mod qp_poseidon { use super::runtime_types; #[derive( @@ -27390,6 +27897,18 @@ pub mod api { crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" )] pub struct ReversibleTransactionExtension; + #[derive( + :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, + :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, + Debug, + )] + #[decode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" + )] + #[encode_as_type( + crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" + )] + pub struct WormholeProofRecorderExtension; } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -27450,6 +27969,8 @@ pub mod api { Recovery(runtime_types::pallet_recovery::pallet::Call), #[codec(index = 21)] Assets(runtime_types::pallet_assets::pallet::Call), + #[codec(index = 23)] + Wormhole(runtime_types::pallet_wormhole::pallet::Call), } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -27493,6 +28014,8 @@ pub mod api { Assets(runtime_types::pallet_assets::pallet::Error), #[codec(index = 22)] AssetsHolder(runtime_types::pallet_assets_holder::pallet::Error), + #[codec(index = 23)] + Wormhole(runtime_types::pallet_wormhole::pallet::Error), } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -27542,6 +28065,8 @@ pub mod api { Assets(runtime_types::pallet_assets::pallet::Event), #[codec(index = 22)] AssetsHolder(runtime_types::pallet_assets_holder::pallet::Event), + #[codec(index = 23)] + Wormhole(runtime_types::pallet_wormhole::pallet::Event), } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -28294,28 +28819,6 @@ pub mod api { Mortal255(::core::primitive::u8), } } - pub mod header { - use super::runtime_types; - #[derive( - :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, - :: subxt :: ext :: subxt_core :: ext :: scale_encode :: EncodeAsType, - Debug, - )] - #[decode_as_type( - crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_decode" - )] - #[encode_as_type( - crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" - )] - pub struct Header<_0> { - pub parent_hash: ::subxt::ext::subxt_core::utils::H256, - #[codec(compact)] - pub number: _0, - pub state_root: ::subxt::ext::subxt_core::utils::H256, - pub extrinsics_root: ::subxt::ext::subxt_core::utils::H256, - pub digest: runtime_types::sp_runtime::generic::digest::Digest, - } - } } pub mod proving_trie { use super::runtime_types; diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a5c768e..7bc33af 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -12,8 +12,6 @@ pub mod high_security; pub mod metadata; pub mod preimage; pub mod recovery; -pub mod referenda; -pub mod referenda_decode; pub mod reversible; pub mod runtime; pub mod scheduler; @@ -21,9 +19,9 @@ pub mod send; pub mod storage; pub mod system; pub mod tech_collective; -pub mod tech_referenda; pub mod treasury; pub mod wallet; +pub mod wormhole; /// Main CLI commands #[derive(Subcommand, Debug)] @@ -94,12 +92,6 @@ pub enum Commands { /// Tech Referenda management commands (for runtime upgrade proposals) #[command(subcommand)] Preimage(preimage::PreimageCommands), - #[command(subcommand)] - TechReferenda(tech_referenda::TechReferendaCommands), - - /// Standard Referenda management commands (public governance) - #[command(subcommand)] - Referenda(referenda::ReferendaCommands), /// Treasury management commands #[command(subcommand)] @@ -230,6 +222,10 @@ pub enum Commands { /// Block management and analysis commands #[command(subcommand)] Block(block::BlockCommands), + + /// Wormhole proof generation and verification + #[command(subcommand)] + Wormhole(wormhole::WormholeCommands), } /// Developer subcommands @@ -282,15 +278,6 @@ pub async fn execute_command( .await, Commands::Preimage(preimage_cmd) => preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await, - Commands::TechReferenda(tech_referenda_cmd) => - tech_referenda::handle_tech_referenda_command( - tech_referenda_cmd, - node_url, - execution_mode, - ) - .await, - Commands::Referenda(referenda_cmd) => - referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await, Commands::Treasury(treasury_cmd) => treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await, Commands::Runtime(runtime_cmd) => @@ -366,6 +353,8 @@ pub async fn execute_command( }, Commands::CompatibilityCheck => handle_compatibility_check(node_url).await, Commands::Block(block_cmd) => block::handle_block_command(block_cmd, node_url).await, + Commands::Wormhole(wormhole_cmd) => + wormhole::handle_wormhole_command(wormhole_cmd, node_url).await, } } diff --git a/src/cli/referenda.rs b/src/cli/referenda.rs deleted file mode 100644 index 04f4416..0000000 --- a/src/cli/referenda.rs +++ /dev/null @@ -1,855 +0,0 @@ -//! `quantus referenda` subcommand - manage standard Referenda proposals -use crate::{ - chain::quantus_subxt, cli::common::submit_transaction, error::QuantusError, log_error, - log_print, log_success, log_verbose, -}; -use clap::Subcommand; -use colored::Colorize; -use std::str::FromStr; - -/// Standard Referenda management commands -#[derive(Subcommand, Debug)] -pub enum ReferendaCommands { - /// Submit a simple proposal (System::remark) to test Referenda - SubmitRemark { - /// Message to include in the remark - #[arg(long)] - message: String, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - - /// Origin type: signed (default), none (for signaling track), root - #[arg(long, default_value = "signed")] - origin: String, - }, - - /// Submit a proposal using existing preimage hash - Submit { - /// Preimage hash (must already exist on chain) - #[arg(long)] - preimage_hash: String, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - - /// Origin type: signed (default), none (for signaling track), root - #[arg(long, default_value = "signed")] - origin: String, - }, - - /// List all active Referenda proposals - List, - - /// Get details of a specific Referendum - Get { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Decode and display the proposal call in human-readable format - #[arg(long)] - decode: bool, - }, - - /// Check the status of a Referendum - Status { - /// Referendum index - #[arg(short, long)] - index: u32, - }, - - /// Place a decision deposit for a Referendum - PlaceDecisionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Vote on a Referendum (uses conviction voting) - Vote { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Vote aye (true) or nay (false) - #[arg(long)] - aye: bool, - - /// Conviction (0=None, 1=Locked1x, 2=Locked2x, up to 6=Locked6x) - #[arg(long, default_value = "0")] - conviction: u8, - - /// Amount to vote with - #[arg(long)] - amount: String, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Refund submission deposit for a completed Referendum - RefundSubmissionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name that submitted the referendum - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Refund decision deposit for a completed Referendum - RefundDecisionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name that placed the decision deposit - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Get Referenda configuration - Config, -} - -/// Handle referenda commands -pub async fn handle_referenda_command( - command: ReferendaCommands, - node_url: &str, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; - - match command { - ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } => - submit_remark_proposal( - &quantus_client, - &message, - &from, - password, - password_file, - &origin, - execution_mode, - ) - .await, - ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => - submit_proposal( - &quantus_client, - &preimage_hash, - &from, - password, - password_file, - &origin, - execution_mode, - ) - .await, - ReferendaCommands::List => list_proposals(&quantus_client).await, - ReferendaCommands::Get { index, decode } => - get_proposal_details(&quantus_client, index, decode).await, - ReferendaCommands::Status { index } => get_proposal_status(&quantus_client, index).await, - ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => - place_decision_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - ReferendaCommands::Vote { - index, - aye, - conviction, - amount, - from, - password, - password_file, - } => - vote_on_referendum( - &quantus_client, - index, - aye, - conviction, - &amount, - &from, - password, - password_file, - execution_mode, - ) - .await, - ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => - refund_submission_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => - refund_decision_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - ReferendaCommands::Config => get_config(&quantus_client).await, - } -} - -/// Submit a simple System::remark proposal -async fn submit_remark_proposal( - quantus_client: &crate::chain::client::QuantusClient, - message: &str, - from: &str, - password: Option, - password_file: Option, - origin_type: &str, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - use qp_poseidon::PoseidonHasher; - - log_print!("📝 Submitting System::remark Proposal to Referenda"); - log_print!(" đŸ’Ŧ Message: {}", message.bright_cyan()); - log_print!(" 🔑 Submitted by: {}", from.bright_yellow()); - log_print!(" đŸŽ¯ Origin type: {}", origin_type.bright_magenta()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Build System::remark call and encode it - let remark_bytes = message.as_bytes().to_vec(); - let remark_payload = quantus_subxt::api::tx().system().remark(remark_bytes.clone()); - let metadata = quantus_client.client().metadata(); - let encoded_call = <_ as subxt::tx::Payload>::encode_call_data(&remark_payload, &metadata) - .map_err(|e| QuantusError::Generic(format!("Failed to encode call data: {:?}", e)))?; - - log_verbose!("📝 Encoded call size: {} bytes", encoded_call.len()); - - // Compute preimage hash using Poseidon - let preimage_hash: sp_core::H256 = - ::hash(&encoded_call); - - log_print!("🔗 Preimage hash: {:?}", preimage_hash); - - // Submit Preimage::note_preimage - type PreimageBytes = quantus_subxt::api::preimage::calls::types::note_preimage::Bytes; - let bounded_bytes: PreimageBytes = encoded_call.clone(); - - log_print!("📝 Submitting preimage..."); - let note_preimage_tx = quantus_subxt::api::tx().preimage().note_preimage(bounded_bytes); - let preimage_tx_hash = - submit_transaction(quantus_client, &keypair, note_preimage_tx, None, execution_mode) - .await?; - log_print!("✅ Preimage transaction submitted: {:?}", preimage_tx_hash); - - // Wait for preimage transaction confirmation - log_print!("âŗ Waiting for preimage transaction confirmation..."); - - // Build Referenda::submit call using Lookup preimage reference - type ProposalBounded = - quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded< - quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall, - quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher, - >; - - let preimage_hash_subxt: subxt::utils::H256 = preimage_hash; - let proposal: ProposalBounded = - ProposalBounded::Lookup { hash: preimage_hash_subxt, len: encoded_call.len() as u32 }; - - // Create origin based on origin_type parameter - let account_id_sp = keypair.to_account_id_32(); - let account_id_subxt: subxt::ext::subxt_core::utils::AccountId32 = - subxt::ext::subxt_core::utils::AccountId32(*account_id_sp.as_ref()); - - let origin_caller = match origin_type.to_lowercase().as_str() { - "signed" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Signed( - account_id_subxt, - ); - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - "none" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::None; - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - "root" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - _ => - return Err(QuantusError::Generic(format!( - "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", - origin_type - ))), - }; - - let enactment = - quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After( - 10u32, // Execute 10 blocks after approval - ); - - log_print!("🔧 Creating Referenda::submit call..."); - let submit_call = - quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment); - - let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; - log_print!( - "✅ {} Referendum proposal submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Use 'quantus referenda list' to see active proposals"); - Ok(()) -} - -/// Submit a proposal using existing preimage hash -async fn submit_proposal( - quantus_client: &crate::chain::client::QuantusClient, - preimage_hash: &str, - from: &str, - password: Option, - password_file: Option, - origin_type: &str, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("📝 Submitting Proposal to Referenda"); - log_print!(" 🔗 Preimage hash: {}", preimage_hash.bright_cyan()); - log_print!(" 🔑 Submitted by: {}", from.bright_yellow()); - log_print!(" đŸŽ¯ Origin type: {}", origin_type.bright_magenta()); - - // Parse preimage hash - let hash_str = preimage_hash.trim_start_matches("0x"); - let preimage_hash_parsed: sp_core::H256 = sp_core::H256::from_str(hash_str) - .map_err(|_| QuantusError::Generic("Invalid preimage hash format".to_string()))?; - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Check if preimage exists and get its length - log_print!("🔍 Checking preimage status..."); - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let preimage_status = storage_at - .fetch( - &quantus_subxt::api::storage() - .preimage() - .request_status_for(preimage_hash_parsed), - ) - .await - .map_err(|e| QuantusError::Generic(format!("Failed to fetch preimage status: {:?}", e)))? - .ok_or_else(|| QuantusError::Generic("Preimage not found on chain".to_string()))?; - - let preimage_len = match preimage_status { - quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Unrequested { - ticket: _, - len, - } => len, - quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Requested { - maybe_ticket: _, - count: _, - maybe_len, - } => match maybe_len { - Some(len) => len, - None => return Err(QuantusError::Generic("Preimage length not available".to_string())), - }, - }; - - log_print!("✅ Preimage found! Length: {} bytes", preimage_len); - - // Build Referenda::submit call - type ProposalBounded = - quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded< - quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall, - quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher, - >; - - let preimage_hash_subxt: subxt::utils::H256 = preimage_hash_parsed; - let proposal: ProposalBounded = - ProposalBounded::Lookup { hash: preimage_hash_subxt, len: preimage_len }; - - // Create origin based on origin_type parameter - let account_id_sp = keypair.to_account_id_32(); - let account_id_subxt: subxt::ext::subxt_core::utils::AccountId32 = - subxt::ext::subxt_core::utils::AccountId32(*account_id_sp.as_ref()); - - let origin_caller = match origin_type.to_lowercase().as_str() { - "signed" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Signed( - account_id_subxt, - ); - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - "none" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::None; - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - "root" => { - let raw_origin = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) - }, - _ => - return Err(QuantusError::Generic(format!( - "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", - origin_type - ))), - }; - - let enactment = - quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After( - 10u32, - ); - - log_print!("🔧 Creating Referenda::submit call..."); - let submit_call = - quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment); - - let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; - log_print!( - "✅ {} Referendum proposal submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Use 'quantus referenda list' to see active proposals"); - Ok(()) -} - -/// List recent Referenda proposals -async fn list_proposals( - quantus_client: &crate::chain::client::QuantusClient, -) -> crate::error::Result<()> { - log_print!("📜 Active Referenda Proposals"); - log_print!(""); - - let addr = quantus_subxt::api::storage().referenda().referendum_count(); - - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let count = storage_at.fetch(&addr).await?; - - if let Some(total) = count { - log_print!("📊 Total referenda created: {}", total); - if total == 0 { - log_print!("📭 No active proposals found"); - return Ok(()); - } - log_print!("🔍 Fetching recent referenda..."); - for i in (0..total).rev().take(10) { - get_proposal_status(quantus_client, i).await?; - log_print!("----------------------------------------"); - } - } else { - log_print!("📭 No referenda found - Referenda may be empty"); - } - - Ok(()) -} - -/// Get details of a specific Referendum -async fn get_proposal_details( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - decode: bool, -) -> crate::error::Result<()> { - use quantus_subxt::api::runtime_types::pallet_referenda::types::ReferendumInfo; - - log_print!("📄 Referendum #{} Details", index); - log_print!(""); - - let addr = quantus_subxt::api::storage().referenda().referendum_info_for(index); - - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let info = storage_at.fetch(&addr).await?; - - if let Some(referendum_info) = info { - if decode { - // Try to decode the proposal - match &referendum_info { - ReferendumInfo::Ongoing(status) => { - log_print!("📊 {} Referendum #{}", "Ongoing".bright_green(), index); - log_print!(" đŸ›¤ī¸ Track: {}", status.track); - log_print!(" 📅 Submitted: Block #{}", status.submitted); - log_print!( - " đŸ—ŗī¸ Tally: Ayes: {}, Nays: {}, Support: {}", - status.tally.ayes, - status.tally.nays, - status.tally.support - ); - log_print!(""); - - // Extract preimage hash and length from proposal - if let quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded::Lookup { - hash, - len, - } = &status.proposal - { - log_print!("📝 Proposal Details:"); - log_print!(" 🔗 Preimage Hash: {:?}", hash); - log_print!(" 📏 Length: {} bytes", len); - log_print!(""); - - // Fetch and decode the preimage - match crate::cli::referenda_decode::decode_preimage(quantus_client, hash, *len).await { - Ok(decoded) => { - log_print!("✅ Decoded Proposal:"); - log_print!("{}", decoded); - }, - Err(e) => { - log_print!("âš ī¸ Could not decode proposal: {}", e); - log_print!(" Run 'quantus preimage get --hash {:?} --len {}' to see raw data", hash, len); - }, - } - } else { - log_print!("âš ī¸ Proposal is inline (not a preimage lookup)"); - } - }, - ReferendumInfo::Approved(..) => { - log_print!("📊 {} Referendum #{}", "Approved".green(), index); - log_print!( - " â„šī¸ Proposal details no longer available (referendum finalized)" - ); - }, - ReferendumInfo::Rejected(..) => { - log_print!("📊 {} Referendum #{}", "Rejected".red(), index); - log_print!( - " â„šī¸ Proposal details no longer available (referendum finalized)" - ); - }, - ReferendumInfo::Cancelled(..) => { - log_print!("📊 {} Referendum #{}", "Cancelled".yellow(), index); - log_print!( - " â„šī¸ Proposal details no longer available (referendum finalized)" - ); - }, - ReferendumInfo::TimedOut(..) => { - log_print!("📊 {} Referendum #{}", "TimedOut".dimmed(), index); - log_print!( - " â„šī¸ Proposal details no longer available (referendum finalized)" - ); - }, - ReferendumInfo::Killed(..) => { - log_print!("📊 {} Referendum #{}", "Killed".red().bold(), index); - log_print!(" â„šī¸ Proposal details no longer available (referendum killed)"); - }, - } - } else { - // Raw output (original behavior) - log_print!("📋 Referendum Information (raw):"); - log_print!("{:#?}", referendum_info); - } - } else { - log_print!("📭 Referendum #{} not found", index); - } - Ok(()) -} - -/// Get the status of a Referendum -async fn get_proposal_status( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, -) -> crate::error::Result<()> { - use quantus_subxt::api::runtime_types::pallet_referenda::types::ReferendumInfo; - - log_verbose!("📊 Fetching status for Referendum #{}...", index); - - let addr = quantus_subxt::api::storage().referenda().referendum_info_for(index); - - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let info_res = storage_at.fetch(&addr).await; - - match info_res { - Ok(Some(info)) => { - log_print!("📊 Status for Referendum #{}", index.to_string().bright_yellow()); - match info { - ReferendumInfo::Ongoing(status) => { - log_print!(" - Status: {}", "Ongoing".bright_green()); - log_print!(" - Track: {}", status.track); - log_print!(" - Submitted at: block {}", status.submitted); - log_print!( - " - Tally: Ayes: {}, Nays: {}", - status.tally.ayes, - status.tally.nays - ); - log_verbose!(" - Full status: {:#?}", status); - }, - ReferendumInfo::Approved(submitted, ..) => { - log_print!(" - Status: {}", "Approved".green()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Rejected(submitted, ..) => { - log_print!(" - Status: {}", "Rejected".red()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Cancelled(submitted, ..) => { - log_print!(" - Status: {}", "Cancelled".yellow()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::TimedOut(submitted, ..) => { - log_print!(" - Status: {}", "TimedOut".dimmed()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Killed(submitted) => { - log_print!(" - Status: {}", "Killed".red().bold()); - log_print!(" - Killed at block: {}", submitted); - }, - } - }, - Ok(None) => log_print!("📭 Referendum #{} not found", index), - Err(e) => log_error!("❌ Failed to fetch referendum #{}: {:?}", index, e), - } - - Ok(()) -} - -/// Place a decision deposit for a Referendum -async fn place_decision_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("📋 Placing decision deposit for Referendum #{}", index); - log_print!(" 🔑 Placed by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - let deposit_call = quantus_subxt::api::tx().referenda().place_decision_deposit(index); - let tx_hash = - submit_transaction(quantus_client, &keypair, deposit_call, None, execution_mode).await?; - log_success!("✅ Decision deposit placed! Hash: {:?}", tx_hash.to_string().bright_yellow()); - Ok(()) -} - -/// Vote on a Referendum -async fn vote_on_referendum( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - aye: bool, - conviction: u8, - amount: &str, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("đŸ—ŗī¸ Voting on Referendum #{}", index); - log_print!(" 📊 Vote: {}", if aye { "AYE ✅".bright_green() } else { "NAY ❌".bright_red() }); - log_print!(" 💰 Amount: {}", amount.bright_cyan()); - log_print!(" 🔒 Conviction: {}", conviction); - log_print!(" 🔑 Signed by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Parse amount - let amount_value: u128 = (amount - .parse::() - .map_err(|_| QuantusError::Generic("Invalid amount format".to_string()))? - .max(0.0) * - 1_000_000_000_000_000_000.0) as u128; - - // Validate conviction - if conviction > 6 { - return Err(QuantusError::Generic("Invalid conviction (must be 0-6)".to_string())); - } - - // Build vote - let vote = - quantus_subxt::api::runtime_types::pallet_conviction_voting::vote::AccountVote::Standard { - vote: quantus_subxt::api::runtime_types::pallet_conviction_voting::vote::Vote( - if aye { 128 } else { 0 } | conviction, - ), - balance: amount_value, - }; - - let vote_call = quantus_subxt::api::tx().conviction_voting().vote(index, vote); - let tx_hash = - submit_transaction(quantus_client, &keypair, vote_call, None, execution_mode).await?; - - log_print!( - "✅ {} Vote transaction submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_success!("🎉 {} Vote submitted!", "FINISHED".bright_green().bold()); - Ok(()) -} - -/// Get Referenda configuration -async fn get_config( - quantus_client: &crate::chain::client::QuantusClient, -) -> crate::error::Result<()> { - log_print!("âš™ī¸ Referenda Configuration"); - log_print!(""); - - let constants = quantus_client.client().constants(); - let tracks_addr = quantus_subxt::api::constants().referenda().tracks(); - - match constants.at(&tracks_addr) { - Ok(tracks) => { - log_print!("{}", "📊 Track Configuration:".bold()); - for (id, info) in tracks.iter() { - log_print!(" ------------------------------------"); - log_print!( - " â€ĸ {} #{}: {}", - "Track".bold(), - id, - info.name.to_string().bright_cyan() - ); - log_print!(" â€ĸ Max Deciding: {}", info.max_deciding); - log_print!(" â€ĸ Decision Deposit: {}", info.decision_deposit); - log_print!(" â€ĸ Prepare Period: {} blocks", info.prepare_period); - log_print!(" â€ĸ Decision Period: {} blocks", info.decision_period); - log_print!(" â€ĸ Confirm Period: {} blocks", info.confirm_period); - log_print!(" â€ĸ Min Enactment Period: {} blocks", info.min_enactment_period); - } - log_print!(" ------------------------------------"); - }, - Err(e) => { - log_error!("❌ Failed to decode Tracks constant: {:?}", e); - log_print!("💡 It's possible the Tracks constant is not in the expected format."); - }, - } - - Ok(()) -} - -/// Refund submission deposit for a completed Referendum -async fn refund_submission_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("💰 Refunding submission deposit for Referendum #{}", index); - log_print!(" 🔑 Refund to: {}", from.bright_yellow()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Create refund_submission_deposit call - let refund_call = quantus_subxt::api::tx().referenda().refund_submission_deposit(index); - - let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; - log_print!( - "✅ {} Refund transaction submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Check your balance to confirm the refund"); - Ok(()) -} - -/// Refund decision deposit for a completed Referendum -async fn refund_decision_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("💰 Refunding decision deposit for Referendum #{}", index); - log_print!(" 🔑 Refund to: {}", from.bright_yellow()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Create refund_decision_deposit call - let refund_call = quantus_subxt::api::tx().referenda().refund_decision_deposit(index); - - let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; - log_print!( - "✅ {} Refund transaction submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Check your balance to confirm the refund"); - Ok(()) -} diff --git a/src/cli/referenda_decode.rs b/src/cli/referenda_decode.rs deleted file mode 100644 index 7140fa7..0000000 --- a/src/cli/referenda_decode.rs +++ /dev/null @@ -1,243 +0,0 @@ -//! Decoding utilities for referendum proposals - -use crate::error::QuantusError; -use codec::Decode; -use colored::Colorize; - -/// Decode preimage call data into human-readable format -pub async fn decode_preimage( - quantus_client: &crate::chain::client::QuantusClient, - hash: &subxt::utils::H256, - len: u32, -) -> crate::error::Result { - // Fetch preimage from storage - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let preimage_addr = crate::chain::quantus_subxt::api::storage() - .preimage() - .preimage_for((*hash, len)); - - let preimage_result = storage_at.fetch(&preimage_addr).await; - - let content = match preimage_result { - Ok(Some(bounded_vec)) => bounded_vec.0, - Ok(None) => - return Err(QuantusError::Generic(format!("Preimage not found for hash {:?}", hash))), - Err(e) => return Err(QuantusError::Generic(format!("Error fetching preimage: {:?}", e))), - }; - - // Decode using direct Decode trait (RuntimeCall implements it via DecodeAsType derive) - decode_runtime_call_direct(&content) -} - -/// Decode RuntimeCall directly using Decode trait -fn decode_runtime_call_direct(data: &[u8]) -> crate::error::Result { - // First, let's try to understand the call structure by reading indices - if data.len() < 3 { - return Err(QuantusError::Generic("Call data too short".to_string())); - } - - let pallet_index = data[0]; - let inner_index = data[1]; - let call_index = data[2]; - - match (pallet_index, inner_index, call_index) { - // System pallet (0, 0, X) - // Special case: if call_index looks like Compact (high value like 0xe8), - // it might be remark (call 0) where the call index byte is omitted - (0, 0, idx) if idx > 100 => { - // Likely remark (call 0) with Compact-encoded Vec starting at byte 2 - decode_system_remark_no_index(&data[2..]) - }, - (0, 0, _) => decode_system_call(&data[2..]), - - // TreasuryPallet (18, 5, X) where X is any spend variant (11, 15, 19, etc.) - // Different indices represent different value ranges/encodings - (18, 5, _) => decode_treasury_spend_call(&data[3..]), - - // Unknown - _ => Ok(format!( - " {} {} {} {}\n {} {} bytes\n {}:\n {}", - "Call Indices:".dimmed(), - pallet_index, - inner_index, - call_index, - "Args:".dimmed(), - data.len() - 3, - "Raw Hex".dimmed(), - hex::encode(&data[3..]).bright_green() - )), - } -} - -/// Decode System::remark when call index byte is omitted (call 0) -fn decode_system_remark_no_index(args: &[u8]) -> crate::error::Result { - // args starts directly with Compact-encoded Vec - let mut cursor = args; - let remark_bytes: Vec = Vec::decode(&mut cursor) - .map_err(|e| QuantusError::Generic(format!("Failed to decode remark: {:?}", e)))?; - let remark_str = String::from_utf8_lossy(&remark_bytes); - - Ok(format!( - " {} {}\n {} {}\n {}:\n {} \"{}\"", - "Pallet:".dimmed(), - "System".bright_cyan(), - "Call:".dimmed(), - "remark".bright_yellow(), - "Parameters".dimmed(), - "message:".dimmed(), - remark_str.bright_green() - )) -} - -/// Decode System pallet calls -fn decode_system_call(data_from_call: &[u8]) -> crate::error::Result { - if data_from_call.is_empty() { - return Err(QuantusError::Generic("Empty system call data".to_string())); - } - - let call_index = data_from_call[0]; - let args = &data_from_call[1..]; - - match call_index { - 0 => { - // remark - standard Vec - let mut cursor = args; - let remark_bytes: Vec = Vec::decode(&mut cursor) - .map_err(|e| QuantusError::Generic(format!("Failed to decode remark: {:?}", e)))?; - let remark_str = String::from_utf8_lossy(&remark_bytes); - - Ok(format!( - " {} {}\n {} {}\n {}:\n {} \"{}\"", - "Pallet:".dimmed(), - "System".bright_cyan(), - "Call:".dimmed(), - "remark".bright_yellow(), - "Parameters".dimmed(), - "message:".dimmed(), - remark_str.bright_green() - )) - }, - 1 => { - // remark_with_event - has different encoding, try decoding from byte 1 - let remark_str = if args.len() > 1 { - String::from_utf8_lossy(&args[1..]) - } else { - String::from_utf8_lossy(args) - }; - - Ok(format!( - " {} {}\n {} {}\n {}:\n {} \"{}\"", - "Pallet:".dimmed(), - "System".bright_cyan(), - "Call:".dimmed(), - "remark_with_event".bright_yellow(), - "Parameters".dimmed(), - "message:".dimmed(), - remark_str.bright_green() - )) - }, - 7 => { - // set_code - Ok(format!( - " {} {}\n {} {} {}\n {} {}", - "Pallet:".dimmed(), - "System".bright_cyan(), - "Call:".dimmed(), - "set_code".bright_yellow(), - "(Runtime Upgrade)".dimmed(), - "Parameters:".dimmed(), - "".bright_green() - )) - }, - _ => Ok(format!( - " {} {}\n {} {} (index {})", - "Pallet:".dimmed(), - "System".bright_cyan(), - "Call:".dimmed(), - "unknown".yellow(), - call_index - )), - } -} - -/// Decode TreasuryPallet::spend call arguments -/// The amount is stored as variable-length u128 in little-endian -fn decode_treasury_spend_call(args: &[u8]) -> crate::error::Result { - use sp_core::crypto::Ss58Codec; - - crate::log_verbose!("Decoding treasury spend, args length: {} bytes", args.len()); - crate::log_verbose!("Args hex: {}", hex::encode(args)); - - if args.len() < 34 { - return Err(QuantusError::Generic(format!( - "Args too short for treasury spend: {} bytes (expected 40-42)", - args.len() - ))); - } - - // Structure (discovered through empirical analysis): - // - asset_kind: Box<()> = 0 bytes (unit type has no encoding) - // - amount: u128 = variable bytes (7-8 bytes typically) as little-endian - // - beneficiary: Box = 32 bytes (no variant byte!) - // - valid_from: Option = 1 byte (0x00 for None) - - // The amount length varies based on the value: - // - Small values (< 256TB): 7 bytes - // - Larger values: 8+ bytes - // Total length is typically 40 bytes (7+32+1) or 42 bytes (8+32+1) or similar - - // Calculate amount bytes length: total - 32 (beneficiary) - 1 (valid_from) - let amount_bytes_len = args.len() - 32 - 1; - if !(1..=16).contains(&amount_bytes_len) { - return Err(QuantusError::Generic(format!( - "Invalid amount bytes length: {}", - amount_bytes_len - ))); - } - - // Decode amount: first N bytes as little-endian u128 - let mut amount_bytes_extended = [0u8; 16]; - amount_bytes_extended[..amount_bytes_len].copy_from_slice(&args[..amount_bytes_len]); - let amount = u128::from_le_bytes(amount_bytes_extended); - - // Decode beneficiary: starts after amount bytes, 32 bytes - let beneficiary_start = amount_bytes_len; - let account_bytes: [u8; 32] = args[beneficiary_start..beneficiary_start + 32] - .try_into() - .map_err(|_| QuantusError::Generic("Failed to extract beneficiary bytes".to_string()))?; - let sp_account = sp_core::crypto::AccountId32::from(account_bytes); - let ss58 = sp_account.to_ss58check_with_version(sp_core::crypto::Ss58AddressFormat::custom(42)); - let beneficiary_str = format!("{} ({}...{})", ss58, &ss58[..8], &ss58[ss58.len() - 6..]); - - // Decode valid_from: last byte - let valid_from_byte = args[args.len() - 1]; - let valid_from_str = if valid_from_byte == 0 { - "None (immediate)".to_string() - } else { - format!("Some (byte: 0x{:02x})", valid_from_byte) - }; - - // Format amount in QUAN (1 QUAN = 10^12) - let quan = amount as f64 / 1_000_000_000_000.0; - - Ok(format!( - " {} {}\n {} {}\n {}:\n {} {} {} ({} raw)\n {} {}\n {} {}\n\n {} {}", - "Pallet:".dimmed(), - "TreasuryPallet".bright_cyan(), - "Call:".dimmed(), - "spend".bright_yellow(), - "Parameters".dimmed(), - "amount:".dimmed(), - quan.to_string().bright_green().bold(), - "QUAN".bright_green(), - amount, - "beneficiary:".dimmed(), - beneficiary_str.bright_green(), - "valid_from:".dimmed(), - valid_from_str.bright_green(), - "💡 Info:".cyan(), - "Vote YES if you approve this Treasury spend, NO to reject.".cyan() - )) -} diff --git a/src/cli/tech_referenda.rs b/src/cli/tech_referenda.rs deleted file mode 100644 index 6fc8860..0000000 --- a/src/cli/tech_referenda.rs +++ /dev/null @@ -1,771 +0,0 @@ -//! `quantus tech-referenda` subcommand - manage Tech Referenda proposals -use crate::{ - chain::quantus_subxt, cli::common::submit_transaction, error::QuantusError, log_error, - log_print, log_success, log_verbose, -}; -use clap::Subcommand; -use colored::Colorize; -use std::{path::PathBuf, str::FromStr}; - -/// Tech Referenda management commands -#[derive(Subcommand, Debug)] -pub enum TechReferendaCommands { - /// Submit a runtime upgrade proposal to Tech Referenda (requires existing preimage) - Submit { - /// Preimage hash (must already exist on chain) - #[arg(long)] - preimage_hash: String, - - /// Wallet name to sign with (must be a Tech Collective member or root) - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Submit a runtime upgrade proposal to Tech Referenda (creates preimage first) - SubmitWithPreimage { - /// Path to the runtime WASM file - #[arg(short, long)] - wasm_file: PathBuf, - - /// Wallet name to sign with (must be a Tech Collective member or root) - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// List all active Tech Referenda proposals - List, - - /// Get details of a specific Tech Referendum - Get { - /// Referendum index - #[arg(short, long)] - index: u32, - }, - - /// Check the status of a Tech Referendum - Status { - /// Referendum index - #[arg(short, long)] - index: u32, - }, - - /// Place a decision deposit for a Tech Referendum - PlaceDecisionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Cancel a Tech Referendum (requires root permissions) - Cancel { - /// Referendum index to cancel - #[arg(short, long)] - index: u32, - - /// Wallet name to sign with (must have root permissions) - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Kill a Tech Referendum (requires root permissions) - Kill { - /// Referendum index to kill - #[arg(short, long)] - index: u32, - - /// Wallet name to sign with (must have root permissions) - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Nudge a Tech Referendum to next phase (sudo origin) - Nudge { - /// Referendum index to nudge - #[arg(short, long)] - index: u32, - - /// Wallet name to sign with - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Refund submission deposit for a completed Tech Referendum - RefundSubmissionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name that submitted the referendum - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Refund decision deposit for a completed Tech Referendum - RefundDecisionDeposit { - /// Referendum index - #[arg(short, long)] - index: u32, - - /// Wallet name that placed the decision deposit - #[arg(short, long)] - from: String, - - /// Password for the wallet - #[arg(short, long)] - password: Option, - - /// Read password from file - #[arg(long)] - password_file: Option, - }, - - /// Get Tech Referenda configuration - Config, -} - -/// Handle tech referenda commands -pub async fn handle_tech_referenda_command( - command: TechReferendaCommands, - node_url: &str, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; - - match command { - TechReferendaCommands::Submit { preimage_hash, from, password, password_file } => - submit_runtime_upgrade( - &quantus_client, - &preimage_hash, - &from, - password, - password_file, - execution_mode, - ) - .await, - TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => - submit_runtime_upgrade_with_preimage( - &quantus_client, - &wasm_file, - &from, - password, - password_file, - execution_mode, - ) - .await, - TechReferendaCommands::List => list_proposals(&quantus_client).await, - TechReferendaCommands::Get { index } => get_proposal_details(&quantus_client, index).await, - TechReferendaCommands::Status { index } => - get_proposal_status(&quantus_client, index).await, - TechReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => - place_decision_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - TechReferendaCommands::Cancel { index, from, password, password_file } => - cancel_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::Kill { index, from, password, password_file } => - kill_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::Nudge { index, from, password, password_file } => - nudge_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => - refund_submission_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => - refund_decision_deposit( - &quantus_client, - index, - &from, - password, - password_file, - execution_mode, - ) - .await, - TechReferendaCommands::Config => get_config(&quantus_client).await, - } -} - -/// Submit a runtime upgrade proposal to Tech Referenda (uses existing preimage) -async fn submit_runtime_upgrade( - quantus_client: &crate::chain::client::QuantusClient, - preimage_hash: &str, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("📝 Submitting Runtime Upgrade Proposal to Tech Referenda"); - log_print!(" 🔗 Preimage hash: {}", preimage_hash.bright_cyan()); - log_print!(" 🔑 Submitted by: {}", from.bright_yellow()); - - // Parse preimage hash (trim 0x) - let hash_str = preimage_hash.trim_start_matches("0x"); - let preimage_hash_parsed: sp_core::H256 = sp_core::H256::from_str(hash_str) - .map_err(|_| QuantusError::Generic("Invalid preimage hash format".to_string()))?; - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Check if preimage exists and get its length - log_print!("🔍 Checking preimage status..."); - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let preimage_status = storage_at - .fetch( - &quantus_subxt::api::storage() - .preimage() - .request_status_for(preimage_hash_parsed), - ) - .await - .map_err(|e| QuantusError::Generic(format!("Failed to fetch preimage status: {:?}", e)))? - .ok_or_else(|| QuantusError::Generic("Preimage not found on chain".to_string()))?; - - let preimage_len = match preimage_status { - quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Unrequested { - ticket: _, - len, - } => len, - quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Requested { - maybe_ticket: _, - count: _, - maybe_len, - } => match maybe_len { - Some(len) => len, - None => return Err(QuantusError::Generic("Preimage length not available".to_string())), - }, - }; - - log_print!("✅ Preimage found! Length: {} bytes", preimage_len); - - // Build TechReferenda::submit call using Lookup preimage reference - type ProposalBounded = - quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded< - quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall, - quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher, - >; - - let preimage_hash_subxt: subxt::utils::H256 = preimage_hash_parsed; - let proposal: ProposalBounded = - ProposalBounded::Lookup { hash: preimage_hash_subxt, len: preimage_len }; - - let raw_origin_root = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; - let origin_caller = - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin_root); - - let enactment = - quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After( - 0u32, - ); - - log_print!("🔧 Creating TechReferenda::submit call..."); - let submit_call = - quantus_subxt::api::tx() - .tech_referenda() - .submit(origin_caller, proposal, enactment); - - let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; - log_print!( - "✅ {} Runtime upgrade proposal submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Use 'quantus tech-referenda list' to see active proposals"); - Ok(()) -} - -/// Submit a runtime upgrade proposal to Tech Referenda (creates preimage first) -async fn submit_runtime_upgrade_with_preimage( - quantus_client: &crate::chain::client::QuantusClient, - wasm_file: &PathBuf, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - use qp_poseidon::PoseidonHasher; - - log_print!("📝 Submitting Runtime Upgrade Proposal to Tech Referenda"); - log_print!(" 📂 WASM file: {}", wasm_file.display().to_string().bright_cyan()); - log_print!(" 🔑 Submitted by: {}", from.bright_yellow()); - - if !wasm_file.exists() { - return Err(QuantusError::Generic(format!("WASM file not found: {}", wasm_file.display()))); - } - - if let Some(ext) = wasm_file.extension() { - if ext != "wasm" { - log_verbose!("âš ī¸ Warning: File doesn't have .wasm extension"); - } - } - - // Read WASM file - let wasm_code = std::fs::read(wasm_file) - .map_err(|e| QuantusError::Generic(format!("Failed to read WASM file: {}", e)))?; - - log_print!("📊 WASM file size: {} bytes", wasm_code.len()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Build a static payload for System::set_code and encode full call data (pallet + call + args) - let set_code_payload = quantus_subxt::api::tx().system().set_code(wasm_code.clone()); - let metadata = quantus_client.client().metadata(); - let encoded_call = <_ as subxt::tx::Payload>::encode_call_data(&set_code_payload, &metadata) - .map_err(|e| QuantusError::Generic(format!("Failed to encode call data: {:?}", e)))?; - - log_verbose!("📝 Encoded call size: {} bytes", encoded_call.len()); - - // Compute preimage hash using Poseidon (runtime uses PoseidonHasher) - let preimage_hash: sp_core::H256 = - ::hash(&encoded_call); - - log_print!("🔗 Preimage hash: {:?}", preimage_hash); - - // Submit Preimage::note_preimage with bounded bytes - type PreimageBytes = quantus_subxt::api::preimage::calls::types::note_preimage::Bytes; - let bounded_bytes: PreimageBytes = encoded_call.clone(); - - log_print!("📝 Submitting preimage..."); - let note_preimage_tx = quantus_subxt::api::tx().preimage().note_preimage(bounded_bytes); - let preimage_tx_hash = - submit_transaction(quantus_client, &keypair, note_preimage_tx, None, execution_mode) - .await?; - log_print!("✅ Preimage transaction submitted: {:?}", preimage_tx_hash); - - // Wait for preimage transaction confirmation - log_print!("âŗ Waiting for preimage transaction confirmation..."); - - // Build TechReferenda::submit call using Lookup preimage reference - type ProposalBounded = - quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded< - quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall, - quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher, - >; - - let preimage_hash_subxt: subxt::utils::H256 = preimage_hash; - let proposal: ProposalBounded = - ProposalBounded::Lookup { hash: preimage_hash_subxt, len: encoded_call.len() as u32 }; - - let raw_origin_root = - quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; - let origin_caller = - quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin_root); - - let enactment = - quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After( - 0u32, - ); - - log_print!("🔧 Creating TechReferenda::submit call..."); - let submit_call = - quantus_subxt::api::tx() - .tech_referenda() - .submit(origin_caller, proposal, enactment); - - let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; - log_print!( - "✅ {} Runtime upgrade proposal submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_print!("💡 Use 'quantus tech-referenda list' to see active proposals"); - Ok(()) -} - -/// List recent Tech Referenda proposals -async fn list_proposals( - quantus_client: &crate::chain::client::QuantusClient, -) -> crate::error::Result<()> { - log_print!("📜 Active Tech Referenda Proposals"); - log_print!(""); - - let addr = quantus_subxt::api::storage().tech_referenda().referendum_count(); - - // Get the latest block hash to read from the latest state (not finalized) - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let count = storage_at.fetch(&addr).await?; - - if let Some(total) = count { - log_print!("📊 Total referenda created: {}", total); - if total == 0 { - log_print!("📭 No active proposals found"); - return Ok(()); - } - log_print!("🔍 Fetching recent referenda..."); - for i in (0..total).rev().take(10) { - get_proposal_status(quantus_client, i).await?; - log_print!("----------------------------------------"); - } - } else { - log_print!("📭 No referenda found - Tech Referenda may be empty"); - } - - Ok(()) -} - -/// Get details of a specific Tech Referendum -async fn get_proposal_details( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, -) -> crate::error::Result<()> { - log_print!("📄 Tech Referendum #{} Details", index); - log_print!(""); - - let addr = quantus_subxt::api::storage().tech_referenda().referendum_info_for(index); - - // Get the latest block hash to read from the latest state (not finalized) - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let info = storage_at.fetch(&addr).await?; - - if let Some(referendum_info) = info { - log_print!("📋 Referendum Information (raw):"); - log_print!("{:#?}", referendum_info); - } else { - log_print!("📭 Referendum #{} not found", index); - } - Ok(()) -} - -/// Get the status of a Tech Referendum -async fn get_proposal_status( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, -) -> crate::error::Result<()> { - use quantus_subxt::api::runtime_types::pallet_referenda::types::ReferendumInfo; - - log_verbose!("📊 Fetching status for Tech Referendum #{}...", index); - - let addr = quantus_subxt::api::storage().tech_referenda().referendum_info_for(index); - - // Get the latest block hash to read from the latest state (not finalized) - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - - let info_res = storage_at.fetch(&addr).await; - - match info_res { - Ok(Some(info)) => { - log_print!("📊 Status for Referendum #{}", index.to_string().bright_yellow()); - match info { - ReferendumInfo::Ongoing(status) => { - log_print!(" - Status: {}", "Ongoing".bright_green()); - log_print!(" - Track: {}", status.track); - log_print!(" - Submitted at: block {}", status.submitted); - log_print!( - " - Tally: Ayes: {}, Nays: {}", - status.tally.ayes, - status.tally.nays - ); - log_verbose!(" - Full status: {:#?}", status); - }, - ReferendumInfo::Approved(submitted, ..) => { - log_print!(" - Status: {}", "Approved".green()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Rejected(submitted, ..) => { - log_print!(" - Status: {}", "Rejected".red()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Cancelled(submitted, ..) => { - log_print!(" - Status: {}", "Cancelled".yellow()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::TimedOut(submitted, ..) => { - log_print!(" - Status: {}", "TimedOut".dimmed()); - log_print!(" - Submitted at block: {}", submitted); - }, - ReferendumInfo::Killed(submitted) => { - log_print!(" - Status: {}", "Killed".red().bold()); - log_print!(" - Killed at block: {}", submitted); - }, - } - }, - Ok(None) => log_print!("📭 Referendum #{} not found", index), - Err(e) => log_error!("❌ Failed to fetch referendum #{}: {:?}", index, e), - } - - Ok(()) -} - -/// Place a decision deposit for a Tech Referendum -async fn place_decision_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("📋 Placing decision deposit for Tech Referendum #{}", index); - log_print!(" 🔑 Placed by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - let deposit_call = quantus_subxt::api::tx().tech_referenda().place_decision_deposit(index); - let tx_hash = - submit_transaction(quantus_client, &keypair, deposit_call, None, execution_mode).await?; - log_success!("✅ Decision deposit placed! Hash: {:?}", tx_hash.to_string().bright_yellow()); - Ok(()) -} - -/// Cancel a Tech Referendum (sudo) -async fn cancel_proposal( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("❌ Cancelling Tech Referendum #{}", index); - log_print!(" 🔑 Cancelled by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - let inner = - quantus_subxt::api::Call::TechReferenda(quantus_subxt::api::tech_referenda::Call::cancel { - index, - }); - let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - - let tx_hash = - submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; - log_success!("✅ Referendum cancelled! Hash: {:?}", tx_hash.to_string().bright_yellow()); - Ok(()) -} - -/// Kill a Tech Referendum (sudo) -async fn kill_proposal( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("💀 Killing Tech Referendum #{}", index); - log_print!(" 🔑 Killed by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - let inner = - quantus_subxt::api::Call::TechReferenda(quantus_subxt::api::tech_referenda::Call::kill { - index, - }); - let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - - let tx_hash = - submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; - log_success!("✅ Referendum killed! Hash: {:?}", tx_hash.to_string().bright_yellow()); - Ok(()) -} - -/// Nudge a Tech Referendum to next phase (sudo) -async fn nudge_proposal( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("🔄 Nudging Tech Referendum #{}", index); - log_print!(" 🔑 Nudged by: {}", from.bright_yellow()); - - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - let inner = quantus_subxt::api::Call::TechReferenda( - quantus_subxt::api::tech_referenda::Call::nudge_referendum { index }, - ); - let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - - let tx_hash = - submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; - log_success!("✅ Referendum nudged! Hash: {:?}", tx_hash.to_string().bright_yellow()); - Ok(()) -} - -/// Get Tech Referenda configuration -async fn get_config( - quantus_client: &crate::chain::client::QuantusClient, -) -> crate::error::Result<()> { - log_print!("âš™ī¸ Tech Referenda Configuration"); - log_print!(""); - - let constants = quantus_client.client().constants(); - let tracks_addr = quantus_subxt::api::constants().tech_referenda().tracks(); - - match constants.at(&tracks_addr) { - Ok(tracks) => { - log_print!("{}", "📊 Track Configuration:".bold()); - for (id, info) in tracks.iter() { - log_print!(" ------------------------------------"); - log_print!( - " â€ĸ {} #{}: {}", - "Track".bold(), - id, - info.name.to_string().bright_cyan() - ); - log_print!(" â€ĸ Max Deciding: {}", info.max_deciding); - log_print!(" â€ĸ Decision Deposit: {}", info.decision_deposit); - log_print!(" â€ĸ Prepare Period: {} blocks", info.prepare_period); - log_print!(" â€ĸ Decision Period: {} blocks", info.decision_period); - log_print!(" â€ĸ Confirm Period: {} blocks", info.confirm_period); - log_print!(" â€ĸ Min Enactment Period: {} blocks", info.min_enactment_period); - } - log_print!(" ------------------------------------"); - }, - Err(e) => { - log_error!("❌ Failed to decode Tracks constant: {:?}", e); - log_print!("💡 It's possible the Tracks constant is not in the expected format."); - }, - } - - Ok(()) -} - -/// Refund submission deposit for a completed Tech Referendum -async fn refund_submission_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("💰 Refunding submission deposit for Tech Referendum #{}", index); - log_print!(" 🔑 Refund to: {}", from.bright_yellow()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Create refund_submission_deposit call for TechReferenda instance - let refund_call = quantus_subxt::api::tx().tech_referenda().refund_submission_deposit(index); - - let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; - log_print!( - "✅ {} Refund transaction submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_success!("🎉 {} Submission deposit refunded!", "FINISHED".bright_green().bold()); - log_print!("💡 Check your balance to confirm the refund"); - Ok(()) -} - -/// Refund decision deposit for a completed Tech Referendum -async fn refund_decision_deposit( - quantus_client: &crate::chain::client::QuantusClient, - index: u32, - from: &str, - password: Option, - password_file: Option, - execution_mode: crate::cli::common::ExecutionMode, -) -> crate::error::Result<()> { - log_print!("💰 Refunding decision deposit for Tech Referendum #{}", index); - log_print!(" 🔑 Refund to: {}", from.bright_yellow()); - - // Load wallet keypair - let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?; - - // Create refund_decision_deposit call for TechReferenda instance - let refund_call = quantus_subxt::api::tx().tech_referenda().refund_decision_deposit(index); - - let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; - log_print!( - "✅ {} Refund transaction submitted! Hash: {:?}", - "SUCCESS".bright_green().bold(), - tx_hash - ); - - log_success!("🎉 {} Decision deposit refunded!", "FINISHED".bright_green().bold()); - log_print!("💡 Check your balance to confirm the refund"); - Ok(()) -} diff --git a/src/cli/wormhole.rs b/src/cli/wormhole.rs new file mode 100644 index 0000000..a43b10a --- /dev/null +++ b/src/cli/wormhole.rs @@ -0,0 +1,438 @@ +use crate::{ + chain::{ + client::{ChainConfig, QuantusClient}, + quantus_subxt::{self as quantus_node, api::wormhole}, + }, + cli::common::{submit_transaction, ExecutionMode}, + log_print, log_success, log_verbose, + wallet::QuantumKeyPair, +}; +use clap::Subcommand; +use plonky2::plonk::{circuit_data::CircuitConfig, proof::ProofWithPublicInputs}; +use qp_poseidon::PoseidonHasher; +use qp_wormhole_circuit::{ + inputs::{CircuitInputs, PrivateCircuitInputs, PublicCircuitInputs}, + nullifier::Nullifier, +}; +use qp_wormhole_prover::WormholeProver; +use qp_zk_circuits_common::{ + storage_proof::prepare_proof_for_circuit, + utils::{BytesDigest, Digest}, +}; +use sp_core::{ + crypto::{AccountId32, Ss58Codec}, + Hasher, +}; +use subxt::{ + backend::legacy::rpc_methods::ReadProof, + blocks::Block, + ext::{ + codec::Encode, + jsonrpsee::{core::client::ClientT, rpc_params}, + }, + utils::{to_hex, AccountId32 as SubxtAccountId}, + OnlineClient, +}; + +/// Native asset id +const NATIVE_ASSET_ID: u32 = 0; + +#[derive(Subcommand, Debug)] +pub enum WormholeCommands { + /// Generate a wormhole proof + Generate { + /// Secret (32-byte hex string) + #[arg(long)] + secret: String, + + /// Funding amount to transfer + #[arg(long)] + amount: u128, + + /// Exit account (where funds will be withdrawn) + #[arg(long)] + exit_account: String, + + /// Wallet name to fund from + #[arg(short, long)] + from: String, + + /// Password for the wallet + #[arg(short, long)] + password: Option, + + /// Read password from file + #[arg(long)] + password_file: Option, + + /// Output file for the proof (default: proof.hex) + #[arg(short, long, default_value = "proof.hex")] + output: String, + }, + /// Verify a wormhole proof on-chain + Verify { + /// Path to the proof file (hex-encoded) + #[arg(short, long, default_value = "proof.hex")] + proof: String, + }, +} + +pub async fn handle_wormhole_command( + command: WormholeCommands, + node_url: &str, +) -> crate::error::Result<()> { + match command { + WormholeCommands::Generate { + secret, + amount, + exit_account, + from, + password, + password_file, + output, + } => + generate_proof( + secret, + amount, + exit_account, + from, + password, + password_file, + output, + node_url, + ) + .await, + WormholeCommands::Verify { proof } => verify_proof(proof, node_url).await, + } +} + +pub type TransferProofKey = (u32, u64, AccountId32, AccountId32, u128); + +async fn generate_proof( + secret_hex: String, + funding_amount: u128, + exit_account_str: String, + from_wallet: String, + password: Option, + password_file: Option, + output_file: String, + node_url: &str, +) -> crate::error::Result<()> { + log_print!("Generating wormhole proof..."); + + // Parse secret + let secret_bytes = hex::decode(secret_hex.trim_start_matches("0x")) + .map_err(|e| crate::error::QuantusError::Generic(format!("Invalid secret hex: {}", e)))?; + if secret_bytes.len() != 32 { + return Err(crate::error::QuantusError::Generic( + "Secret must be exactly 32 bytes".to_string(), + )); + } + let secret_array: [u8; 32] = secret_bytes + .try_into() + .map_err(|_| crate::error::QuantusError::Generic("Failed to convert secret".to_string()))?; + let secret: BytesDigest = secret_array.try_into().map_err(|e| { + crate::error::QuantusError::Generic(format!("Failed to convert secret: {:?}", e)) + })?; + + // Parse exit account + let exit_account_id = if let Some(exit_account) = exit_account_str.strip_prefix("0x") { + let exit_account_bytes = hex::decode(exit_account).map_err(|e| { + crate::error::QuantusError::Generic(format!("Invalid exit account hex: {}", e)) + })?; + if exit_account_bytes.len() != 32 { + return Err(crate::error::QuantusError::Generic( + "Exit account must be 32 bytes".to_string(), + )); + } + SubxtAccountId(exit_account_bytes.try_into().map_err(|_| { + crate::error::QuantusError::Generic("Failed to convert exit account".to_string()) + })?) + } else { + // Assume it's a wallet name, resolve it + let resolved = crate::cli::common::resolve_address(&exit_account_str)?; + let account_id = AccountId32::from_ss58check(&resolved).map_err(|e| { + crate::error::QuantusError::Generic(format!("Invalid SS58 address: {}", e)) + })?; + let bytes: [u8; 32] = account_id.into(); + SubxtAccountId(bytes) + }; + + // Load keypair + let keypair = crate::wallet::load_keypair_from_wallet(&from_wallet, password, password_file)?; + + // Connect to node + let quantus_client = QuantusClient::new(node_url) + .await + .map_err(|e| crate::error::QuantusError::Generic(format!("Failed to connect: {}", e)))?; + let client = quantus_client.client(); + + log_verbose!("Connected to node"); + + let funding_account = AccountId32::new(PoseidonHasher::hash(keypair.public_key.as_ref()).0); + + // Generate unspendable account + let unspendable_account = + qp_wormhole_circuit::unspendable_account::UnspendableAccount::from_secret(secret) + .account_id; + let unspendable_account_bytes_digest = + qp_zk_circuits_common::utils::digest_felts_to_bytes(unspendable_account); + let unspendable_account_bytes: [u8; 32] = unspendable_account_bytes_digest + .as_ref() + .try_into() + .expect("BytesDigest is always 32 bytes"); + let unspendable_account_id = SubxtAccountId(unspendable_account_bytes); + + log_verbose!("Unspendable account: {:?}", &unspendable_account_id); + log_verbose!("Exit account: {:?}", &exit_account_id); + + // Transfer to unspendable account + let transfer_tx = quantus_node::api::tx().balances().transfer_keep_alive( + subxt::ext::subxt_core::utils::MultiAddress::Id(unspendable_account_id.clone()), + funding_amount, + ); + + log_verbose!("Submitting transfer to unspendable account..."); + + let blocks = at_best_block(&quantus_client) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let block_hash_pre = blocks.hash(); + + let storage_api = client.storage().at(block_hash_pre); + let transfer_count_previous = storage_api + .fetch(&quantus_node::api::storage().wormhole().transfer_count()) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))? + .unwrap_or_default(); + + let quantum_keypair = QuantumKeyPair { + public_key: keypair.public_key.clone(), + private_key: keypair.private_key.clone(), + }; + + submit_transaction( + &quantus_client, + &quantum_keypair, + transfer_tx, + None, + ExecutionMode { finalized: false, wait_for_transaction: true }, + ) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let blocks = at_best_block(&quantus_client) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let block_hash = blocks.hash(); + + log_success!("Transfer included in block: {:?}", block_hash); + + let events_api = client + .events() + .at(block_hash) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let event = events_api + .find::() + .next() + .ok_or_else(|| { + crate::error::QuantusError::Generic("No TransferProofStored event found".to_string()) + })? + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let storage_api = client.storage().at(block_hash); + let transfer_count = storage_api + .fetch(&quantus_node::api::storage().wormhole().transfer_count()) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))? + .unwrap_or_default(); + + if transfer_count <= transfer_count_previous { + return Err(crate::error::QuantusError::Generic( + "Transfer count was not incremented".to_string(), + )); + } + + // Get storage proof + let leaf_hash = qp_poseidon::PoseidonHasher::hash_storage::( + &( + NATIVE_ASSET_ID, + event.transfer_count, + event.from.clone(), + event.to.clone(), + event.amount, + ) + .encode(), + ); + let proof_address = quantus_node::api::storage().wormhole().transfer_proof(( + NATIVE_ASSET_ID, + event.transfer_count, + event.from.clone(), + event.to.clone(), + event.amount, + )); + let mut final_key = proof_address.to_root_bytes(); + final_key.extend_from_slice(&leaf_hash); + let val = storage_api + .fetch_raw(final_key.clone()) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + if val.is_none() { + return Err(crate::error::QuantusError::Generic("Storage key not found".to_string())); + } + + let proof_params = rpc_params![vec![to_hex(&final_key)], block_hash]; + let read_proof: ReadProof = quantus_client + .rpc_client() + .request("state_getReadProof", proof_params) + .await + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let header = blocks.header(); + + let state_root = BytesDigest::try_from(header.state_root.as_bytes()) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let parent_hash = BytesDigest::try_from(header.parent_hash.as_bytes()) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let extrinsics_root = BytesDigest::try_from(header.extrinsics_root.as_bytes()) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let digest = + header.digest.encode().try_into().map_err(|_| { + crate::error::QuantusError::Generic("Failed to encode digest".to_string()) + })?; + + let block_number = header.number; + + // Prepare storage proof + let processed_storage_proof = prepare_proof_for_circuit( + read_proof.proof.iter().map(|proof| proof.0.clone()).collect(), + hex::encode(header.state_root.0), + leaf_hash, + ) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let inputs = CircuitInputs { + private: PrivateCircuitInputs { + secret, + transfer_count: event.transfer_count, + funding_account: BytesDigest::try_from(funding_account.as_ref() as &[u8]) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?, + storage_proof: processed_storage_proof, + unspendable_account: Digest::from(unspendable_account).into(), + state_root, + extrinsics_root, + digest, + }, + public: PublicCircuitInputs { + funding_amount, + nullifier: Nullifier::from_preimage(secret, event.transfer_count).hash.into(), + exit_account: BytesDigest::try_from(exit_account_id.as_ref() as &[u8]) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?, + block_hash: BytesDigest::try_from(block_hash.as_ref()) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?, + parent_hash, + block_number, + asset_id: NATIVE_ASSET_ID, + }, + }; + + log_verbose!("Generating ZK proof..."); + let config = CircuitConfig::standard_recursion_config(); + let prover = WormholeProver::new(config); + let prover_next = prover + .commit(&inputs) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + let proof: ProofWithPublicInputs<_, _, 2> = prover_next.prove().map_err(|e| { + crate::error::QuantusError::Generic(format!("Proof generation failed: {}", e)) + })?; + + let public_inputs = PublicCircuitInputs::try_from(&proof) + .map_err(|e| crate::error::QuantusError::Generic(e.to_string()))?; + + let proof_hex = hex::encode(proof.to_bytes()); + std::fs::write(&output_file, proof_hex).map_err(|e| { + crate::error::QuantusError::Generic(format!("Failed to write proof: {}", e)) + })?; + + log_success!("Proof generated successfully!"); + log_success!("Output: {}", output_file); + log_verbose!("Public inputs: {:?}", public_inputs); + + Ok(()) +} + +async fn at_best_block( + quantus_client: &QuantusClient, +) -> anyhow::Result>> { + let best_block = quantus_client.get_latest_block().await?; + let block = quantus_client.client().blocks().at(best_block).await?; + Ok(block) +} + +async fn verify_proof(proof_file: String, node_url: &str) -> crate::error::Result<()> { + use subxt::tx::TxStatus; + + log_print!("Verifying wormhole proof on-chain..."); + + // Read proof from file + let proof_hex = std::fs::read_to_string(&proof_file).map_err(|e| { + crate::error::QuantusError::Generic(format!("Failed to read proof file: {}", e)) + })?; + + let proof_bytes = hex::decode(proof_hex.trim()) + .map_err(|e| crate::error::QuantusError::Generic(format!("Failed to decode hex: {}", e)))?; + + log_verbose!("Proof size: {} bytes", proof_bytes.len()); + + // Connect to node + let quantus_client = QuantusClient::new(node_url) + .await + .map_err(|e| crate::error::QuantusError::Generic(format!("Failed to connect: {}", e)))?; + + log_verbose!("Connected to node"); + + // Create the verify transaction payload + let verify_tx = quantus_node::api::tx().wormhole().verify_wormhole_proof(proof_bytes); + + log_verbose!("Submitting unsigned verification transaction..."); + + // Submit as unsigned extrinsic + let unsigned_tx = quantus_client.client().tx().create_unsigned(&verify_tx).map_err(|e| { + crate::error::QuantusError::Generic(format!("Failed to create unsigned tx: {}", e)) + })?; + + let mut tx_progress = unsigned_tx + .submit_and_watch() + .await + .map_err(|e| crate::error::QuantusError::Generic(format!("Failed to submit tx: {}", e)))?; + + // Wait for transaction inclusion + while let Some(Ok(status)) = tx_progress.next().await { + log_verbose!("Transaction status: {:?}", status); + match status { + TxStatus::InBestBlock(tx_in_block) => { + let block_hash = tx_in_block.block_hash(); + log_success!("Proof verified successfully on-chain!"); + log_verbose!("Included in block: {:?}", block_hash); + return Ok(()); + }, + TxStatus::InFinalizedBlock(tx_in_block) => { + let block_hash = tx_in_block.block_hash(); + log_success!("Proof verified successfully on-chain!"); + log_verbose!("Finalized in block: {:?}", block_hash); + return Ok(()); + }, + TxStatus::Error { message } | TxStatus::Invalid { message } => { + return Err(crate::error::QuantusError::Generic(format!( + "Transaction failed: {}", + message + ))); + }, + _ => continue, + } + } + + Err(crate::error::QuantusError::Generic("Transaction stream ended unexpectedly".to_string())) +} diff --git a/src/quantus_metadata.scale b/src/quantus_metadata.scale index 0e8740a..a4a9a4e 100644 Binary files a/src/quantus_metadata.scale and b/src/quantus_metadata.scale differ