From 76435d714df28f7fb04aaed5b8c5f374bda3783f Mon Sep 17 00:00:00 2001 From: illuzen Date: Tue, 26 May 2026 17:09:49 +0900 Subject: [PATCH 1/5] set num leaves to 7 --- src/bins_consts.rs | 13 ++++++++++--- src/cli/wormhole.rs | 4 ++-- src/collect_rewards_lib.rs | 6 +++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/bins_consts.rs b/src/bins_consts.rs index 068a8f4..b0faf17 100644 --- a/src/bins_consts.rs +++ b/src/bins_consts.rs @@ -3,6 +3,13 @@ /// Shared by `build.rs` and `crate::bins` via `include!`. const VERSION_MARKER: &str = ".quantus-cli-version"; -/// Number of leaf proofs aggregated into a single batch (default for both -/// build-time generation and runtime lazy generation). -const DEFAULT_NUM_LEAF_PROOFS: usize = 16; +/// Number of leaf proofs aggregated into a single batch. +/// +/// 7 is optimal for mobile devices: fits in degree_bits=15 (~1.5 GB peak memory). +/// 8+ leaves require degree_bits=16 (~2.5 GB peak), limiting to 6GB+ devices. +/// +/// Used by: +/// - build.rs: build-time circuit generation +/// - bins.rs: runtime lazy circuit generation +/// - collect_rewards_lib.rs: batching proofs for aggregation +pub const DEFAULT_NUM_LEAF_PROOFS: usize = 7; diff --git a/src/cli/wormhole.rs b/src/cli/wormhole.rs index 01231e9..4406b02 100644 --- a/src/cli/wormhole.rs +++ b/src/cli/wormhole.rs @@ -2793,7 +2793,7 @@ struct DissolveOutput { /// Layer N: 2^(N-1) inputs → 2^N outputs (all below target_size) /// ``` /// -/// Each layer: batch inputs into groups of ≤16, generate proofs, aggregate, verify on-chain. +/// Each layer: batch inputs into groups of ≤DEFAULT_NUM_LEAF_PROOFS, generate proofs, aggregate, verify on-chain. /// The final outputs are small enough to blend with the miner reward noise floor. #[allow(clippy::too_many_arguments)] async fn run_dissolve( @@ -2934,7 +2934,7 @@ async fn run_dissolve( next_secrets.push(derive_wormhole_secret(&wallet.mnemonic, layer, i + 1)?); } - // Process inputs in batches of ≤16 (aggregation batch size) + // Process inputs in batches (aggregation batch size from config) let batch_size = agg_config.num_leaf_proofs; let mut all_next_outputs: Vec = Vec::new(); let num_batches = num_inputs.div_ceil(batch_size); diff --git a/src/collect_rewards_lib.rs b/src/collect_rewards_lib.rs index cb0b38c..e96ced1 100644 --- a/src/collect_rewards_lib.rs +++ b/src/collect_rewards_lib.rs @@ -12,6 +12,7 @@ //! This is designed to be called from the SDK without needing CLI-specific features. use crate::{ + bins::DEFAULT_NUM_LEAF_PROOFS, chain::{ client::QuantusClient, quantus_subxt::{self as quantus_node, api::wormhole}, @@ -227,7 +228,7 @@ pub struct CollectRewardsConfig { /// 1. Derives wormhole address from mnemonic /// 2. Queries Subsquid for pending transfers to that address /// 3. Generates ZK proofs for selected transfers -/// 4. Aggregates proofs into batches (max 16 per batch) +/// 4. Aggregates proofs into batches (max DEFAULT_NUM_LEAF_PROOFS per batch) /// 5. Submits withdrawal transactions to chain /// /// # Arguments @@ -478,9 +479,8 @@ pub async fn collect_rewards( } // Step 5: Aggregate and submit in batches - const MAX_PROOFS_PER_BATCH: usize = 16; let batches: Vec>> = proof_bytes_list - .chunks(MAX_PROOFS_PER_BATCH) + .chunks(DEFAULT_NUM_LEAF_PROOFS) .map(|chunk| chunk.to_vec()) .collect(); From 3f3fe80a118fcf85384a159e2ba9b9f2d15f7e77 Mon Sep 17 00:00:00 2001 From: illuzen Date: Tue, 26 May 2026 17:30:06 +0900 Subject: [PATCH 2/5] update metadata and fix compile errors --- src/chain/quantus_subxt.rs | 1729 ++++++++++++++++++++++-------------- src/cli/high_security.rs | 8 +- src/cli/multisig.rs | 307 ++----- src/cli/reversible.rs | 4 +- src/cli/wallet.rs | 16 +- src/cli/wormhole.rs | 4 +- src/lib.rs | 2 +- src/quantus_metadata.scale | Bin 161568 -> 166660 bytes 8 files changed, 1146 insertions(+), 924 deletions(-) diff --git a/src/chain/quantus_subxt.rs b/src/chain/quantus_subxt.rs index bc15567..9290c93 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; 20usize] = [ + pub static PALLETS: [&str; 21usize] = [ "System", "Timestamp", "Balances", @@ -27,8 +27,9 @@ pub mod api { "AssetsHolder", "Multisig", "Wormhole", + "ZkTree", ]; - pub static RUNTIME_APIS: [&str; 11usize] = [ + pub static RUNTIME_APIS: [&str; 12usize] = [ "Core", "Metadata", "BlockBuilder", @@ -36,6 +37,7 @@ pub mod api { "OffchainWorkerApi", "SessionKeys", "QPoWApi", + "ZkTreeApi", "AccountNonceApi", "TransactionPaymentApi", "TransactionPaymentCallApi", @@ -89,6 +91,9 @@ pub mod api { pub fn q_po_w_api(&self) -> q_po_w_api::QPoWApi { q_po_w_api::QPoWApi } + pub fn zk_tree_api(&self) -> zk_tree_api::ZkTreeApi { + zk_tree_api::ZkTreeApi + } pub fn account_nonce_api(&self) -> account_nonce_api::AccountNonceApi { account_nonce_api::AccountNonceApi } @@ -142,10 +147,9 @@ pub mod api { "execute_block", types::ExecuteBlock { block }, [ - 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, + 180u8, 202u8, 143u8, 166u8, 125u8, 9u8, 195u8, 179u8, 198u8, 129u8, + 73u8, 45u8, 225u8, 244u8, 234u8, 234u8, 177u8, 61u8, 241u8, 26u8, 75u8, + 53u8, 218u8, 66u8, 56u8, 46u8, 81u8, 29u8, 120u8, 51u8, 249u8, 42u8, ], ) } @@ -162,9 +166,9 @@ pub mod api { "initialize_block", types::InitializeBlock { header }, [ - 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, + 147u8, 82u8, 214u8, 164u8, 66u8, 79u8, 193u8, 216u8, 89u8, 29u8, 83u8, + 182u8, 99u8, 81u8, 244u8, 247u8, 88u8, 158u8, 251u8, 224u8, 6u8, 76u8, + 247u8, 87u8, 83u8, 98u8, 177u8, 188u8, 190u8, 219u8, 179u8, 107u8, ], ) } @@ -409,9 +413,9 @@ pub mod api { "finalize_block", types::FinalizeBlock {}, [ - 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, + 183u8, 30u8, 223u8, 196u8, 0u8, 182u8, 94u8, 4u8, 106u8, 92u8, 190u8, + 77u8, 139u8, 95u8, 162u8, 171u8, 99u8, 168u8, 70u8, 165u8, 175u8, + 228u8, 97u8, 27u8, 25u8, 141u8, 244u8, 217u8, 5u8, 95u8, 49u8, 12u8, ], ) } @@ -449,10 +453,10 @@ pub mod api { "check_inherents", types::CheckInherents { block, data }, [ - 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, + 137u8, 14u8, 89u8, 87u8, 225u8, 80u8, 136u8, 255u8, 242u8, 41u8, 90u8, + 91u8, 140u8, 192u8, 112u8, 230u8, 46u8, 19u8, 149u8, 104u8, 153u8, + 122u8, 92u8, 215u8, 161u8, 88u8, 142u8, 248u8, 156u8, 159u8, 203u8, + 132u8, ], ) } @@ -633,10 +637,9 @@ pub mod api { "offchain_worker", types::OffchainWorker { header }, [ - 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, + 143u8, 60u8, 69u8, 66u8, 143u8, 216u8, 150u8, 58u8, 130u8, 32u8, 160u8, + 205u8, 92u8, 9u8, 114u8, 94u8, 74u8, 160u8, 105u8, 199u8, 246u8, 174u8, + 187u8, 111u8, 225u8, 121u8, 82u8, 29u8, 225u8, 115u8, 119u8, 94u8, ], ) } @@ -838,24 +841,6 @@ pub mod api { ], ) } - #[doc = " Get block ema"] - pub fn get_block_time_ema( - &self, - ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< - types::GetBlockTimeEma, - types::get_block_time_ema::output::Output, - > { - ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload::new_static( - "QPoWApi", - "get_block_time_ema", - types::GetBlockTimeEma {}, - [ - 250u8, 101u8, 7u8, 92u8, 2u8, 209u8, 35u8, 184u8, 188u8, 152u8, 196u8, - 182u8, 14u8, 245u8, 245u8, 243u8, 55u8, 180u8, 6u8, 36u8, 123u8, 95u8, - 19u8, 102u8, 37u8, 142u8, 238u8, 97u8, 63u8, 133u8, 233u8, 6u8, - ], - ) - } #[doc = " Get last block timestamp"] pub fn get_last_block_time( &self, @@ -874,6 +859,7 @@ pub mod api { ], ) } + #[doc = " Get last block mining time"] pub fn get_last_block_duration( &self, ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< @@ -1026,25 +1012,6 @@ pub mod api { crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" )] pub struct GetDifficulty {} - pub mod get_block_time_ema { - use super::runtime_types; - pub mod output { - use super::runtime_types; - pub type Output = ::core::primitive::u64; - } - } - #[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 GetBlockTimeEma {} pub mod get_last_block_time { use super::runtime_types; pub mod output { @@ -1177,6 +1144,175 @@ pub mod api { } } } + pub mod zk_tree_api { + use super::{root_mod, runtime_types}; + #[doc = " Runtime API for the ZK Tree pallet."] + #[doc = ""] + #[doc = " Provides methods to query the ZK Merkle tree state and generate proofs."] + pub struct ZkTreeApi; + impl ZkTreeApi { + #[doc = " Get the current root hash of the ZK tree."] + pub fn get_root( + &self, + ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< + types::GetRoot, + types::get_root::output::Output, + > { + ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload::new_static( + "ZkTreeApi", + "get_root", + types::GetRoot {}, + [ + 198u8, 156u8, 112u8, 8u8, 86u8, 226u8, 81u8, 137u8, 207u8, 161u8, + 181u8, 99u8, 42u8, 221u8, 134u8, 50u8, 205u8, 191u8, 124u8, 165u8, + 174u8, 99u8, 193u8, 28u8, 46u8, 125u8, 2u8, 117u8, 173u8, 187u8, 243u8, + 73u8, + ], + ) + } + #[doc = " Get the current number of leaves in the tree."] + pub fn get_leaf_count( + &self, + ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< + types::GetLeafCount, + types::get_leaf_count::output::Output, + > { + ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload::new_static( + "ZkTreeApi", + "get_leaf_count", + types::GetLeafCount {}, + [ + 1u8, 246u8, 191u8, 192u8, 156u8, 247u8, 209u8, 87u8, 187u8, 48u8, 98u8, + 144u8, 34u8, 200u8, 186u8, 202u8, 176u8, 64u8, 93u8, 165u8, 103u8, + 231u8, 77u8, 57u8, 52u8, 14u8, 213u8, 197u8, 118u8, 137u8, 64u8, 193u8, + ], + ) + } + #[doc = " Get the current depth of the tree."] + pub fn get_depth( + &self, + ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< + types::GetDepth, + types::get_depth::output::Output, + > { + ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload::new_static( + "ZkTreeApi", + "get_depth", + types::GetDepth {}, + [ + 251u8, 48u8, 136u8, 161u8, 26u8, 3u8, 205u8, 80u8, 135u8, 48u8, 176u8, + 105u8, 254u8, 86u8, 79u8, 57u8, 70u8, 227u8, 26u8, 48u8, 228u8, 203u8, + 109u8, 59u8, 3u8, 204u8, 30u8, 40u8, 113u8, 62u8, 123u8, 47u8, + ], + ) + } + #[doc = " Get a Merkle proof for a leaf at the given index."] + #[doc = ""] + #[doc = " Returns `None` if the leaf index is out of bounds."] + pub fn get_merkle_proof( + &self, + leaf_index: types::get_merkle_proof::LeafIndex, + ) -> ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload< + types::GetMerkleProof, + types::get_merkle_proof::output::Output, + > { + ::subxt::ext::subxt_core::runtime_api::payload::StaticPayload::new_static( + "ZkTreeApi", + "get_merkle_proof", + types::GetMerkleProof { leaf_index }, + [ + 74u8, 206u8, 166u8, 44u8, 235u8, 100u8, 174u8, 217u8, 16u8, 167u8, + 180u8, 174u8, 192u8, 121u8, 153u8, 163u8, 204u8, 104u8, 52u8, 198u8, + 44u8, 180u8, 144u8, 37u8, 216u8, 58u8, 175u8, 36u8, 50u8, 214u8, 66u8, + 131u8, + ], + ) + } + } + pub mod types { + use super::runtime_types; + pub mod get_root { + use super::runtime_types; + pub mod output { + use super::runtime_types; + pub type Output = [::core::primitive::u8; 32usize]; + } + } + #[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 GetRoot {} + pub mod get_leaf_count { + use super::runtime_types; + pub mod output { + use super::runtime_types; + pub type Output = ::core::primitive::u64; + } + } + #[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 GetLeafCount {} + pub mod get_depth { + use super::runtime_types; + pub mod output { + use super::runtime_types; + pub type Output = ::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" + )] + pub struct GetDepth {} + pub mod get_merkle_proof { + use super::runtime_types; + pub type LeafIndex = ::core::primitive::u64; + pub mod output { + use super::runtime_types; + pub type Output = + ::core::option::Option; + } + } + #[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 GetMerkleProof { + pub leaf_index: get_merkle_proof::LeafIndex, + } + } + } pub mod account_nonce_api { use super::{root_mod, runtime_types}; #[doc = " The API to query account nonce."] @@ -1431,10 +1567,9 @@ pub mod api { "query_call_info", types::QueryCallInfo { call, len }, [ - 251u8, 117u8, 187u8, 14u8, 196u8, 176u8, 208u8, 219u8, 61u8, 234u8, - 23u8, 241u8, 174u8, 156u8, 167u8, 160u8, 89u8, 42u8, 178u8, 155u8, - 190u8, 179u8, 124u8, 114u8, 251u8, 186u8, 67u8, 205u8, 239u8, 51u8, - 177u8, 90u8, + 90u8, 202u8, 9u8, 88u8, 111u8, 175u8, 220u8, 96u8, 150u8, 13u8, 71u8, + 123u8, 120u8, 157u8, 193u8, 172u8, 169u8, 180u8, 196u8, 6u8, 184u8, + 18u8, 24u8, 97u8, 141u8, 50u8, 253u8, 167u8, 244u8, 99u8, 102u8, 235u8, ], ) } @@ -1452,10 +1587,10 @@ pub mod api { "query_call_fee_details", types::QueryCallFeeDetails { call, len }, [ - 213u8, 155u8, 136u8, 5u8, 157u8, 246u8, 224u8, 16u8, 227u8, 103u8, - 222u8, 116u8, 172u8, 213u8, 203u8, 43u8, 153u8, 98u8, 75u8, 158u8, - 131u8, 22u8, 186u8, 186u8, 116u8, 25u8, 242u8, 159u8, 130u8, 122u8, - 152u8, 125u8, + 248u8, 32u8, 253u8, 238u8, 202u8, 178u8, 245u8, 211u8, 219u8, 2u8, + 220u8, 116u8, 141u8, 73u8, 22u8, 47u8, 212u8, 17u8, 197u8, 149u8, + 250u8, 160u8, 205u8, 101u8, 50u8, 121u8, 214u8, 31u8, 8u8, 161u8, 32u8, + 91u8, ], ) } @@ -1885,6 +2020,9 @@ pub mod api { pub fn wormhole(&self) -> wormhole::storage::StorageApi { wormhole::storage::StorageApi } + pub fn zk_tree(&self) -> zk_tree::storage::StorageApi { + zk_tree::storage::StorageApi + } } pub struct TransactionApi; impl TransactionApi { @@ -1952,9 +2090,9 @@ pub mod api { .hash(); runtime_metadata_hash == [ - 95u8, 161u8, 29u8, 63u8, 6u8, 191u8, 169u8, 252u8, 9u8, 18u8, 126u8, 99u8, 29u8, - 6u8, 27u8, 29u8, 251u8, 189u8, 252u8, 166u8, 35u8, 141u8, 155u8, 35u8, 238u8, 85u8, - 244u8, 246u8, 49u8, 113u8, 167u8, 219u8, + 5u8, 105u8, 163u8, 244u8, 68u8, 98u8, 112u8, 250u8, 61u8, 241u8, 1u8, 101u8, 231u8, + 88u8, 118u8, 173u8, 211u8, 132u8, 177u8, 161u8, 104u8, 154u8, 190u8, 71u8, 168u8, + 146u8, 97u8, 224u8, 185u8, 79u8, 69u8, 71u8, ] } pub mod system { @@ -2695,6 +2833,10 @@ pub mod api { use super::runtime_types; pub type Digest = runtime_types::sp_runtime::generic::digest::Digest; } + pub mod zk_tree_root { + use super::runtime_types; + pub type ZkTreeRoot = ::subxt::ext::subxt_core::utils::H256; + } pub mod events { use super::runtime_types; pub type Events = ::subxt::ext::subxt_core::alloc::vec::Vec< @@ -3032,6 +3174,31 @@ pub mod api { ], ) } + #[doc = " ZK tree root for the current block."] + #[doc = ""] + #[doc = " Set by pallet-zk-tree during block finalization. This is included in the"] + #[doc = " block header as a dedicated field (not in digest) to ensure a fixed offset"] + #[doc = " for ZK circuit verification."] + pub fn zk_tree_root( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::zk_tree_root::ZkTreeRoot, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "System", + "ZkTreeRoot", + (), + [ + 20u8, 224u8, 59u8, 4u8, 237u8, 141u8, 176u8, 61u8, 156u8, 45u8, 84u8, + 60u8, 215u8, 14u8, 69u8, 234u8, 53u8, 157u8, 52u8, 242u8, 67u8, 227u8, + 117u8, 93u8, 77u8, 5u8, 210u8, 55u8, 12u8, 170u8, 57u8, 161u8, + ], + ) + } #[doc = " Events deposited for the current block."] #[doc = ""] #[doc = " NOTE: The item is unbound and should therefore never be read on chain."] @@ -3053,10 +3220,9 @@ pub mod api { "Events", (), [ - 114u8, 203u8, 75u8, 252u8, 183u8, 122u8, 99u8, 127u8, 226u8, 41u8, - 125u8, 202u8, 177u8, 177u8, 136u8, 66u8, 221u8, 204u8, 240u8, 189u8, - 146u8, 54u8, 190u8, 211u8, 240u8, 69u8, 233u8, 62u8, 78u8, 177u8, 97u8, - 8u8, + 79u8, 108u8, 22u8, 139u8, 89u8, 135u8, 213u8, 82u8, 213u8, 83u8, 64u8, + 94u8, 29u8, 221u8, 126u8, 130u8, 81u8, 75u8, 93u8, 129u8, 131u8, 82u8, + 61u8, 187u8, 4u8, 106u8, 46u8, 54u8, 179u8, 195u8, 20u8, 71u8, ], ) } @@ -5448,10 +5614,6 @@ pub mod api { use super::runtime_types; pub type CurrentDifficulty = runtime_types::primitive_types::U512; } - pub mod block_time_ema { - use super::runtime_types; - pub type BlockTimeEma = ::core::primitive::u64; - } } pub struct StorageApi; impl StorageApi { @@ -5516,33 +5678,12 @@ pub mod api { ], ) } - pub fn block_time_ema( - &self, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - (), - types::block_time_ema::BlockTimeEma, - ::subxt::ext::subxt_core::utils::Yes, - ::subxt::ext::subxt_core::utils::Yes, - (), - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "QPoW", - "BlockTimeEma", - (), - [ - 43u8, 90u8, 42u8, 54u8, 219u8, 225u8, 181u8, 63u8, 6u8, 66u8, 120u8, - 166u8, 146u8, 52u8, 10u8, 83u8, 54u8, 4u8, 163u8, 40u8, 46u8, 174u8, - 210u8, 217u8, 140u8, 56u8, 194u8, 245u8, 40u8, 164u8, 225u8, 206u8, - ], - ) - } } } pub mod constants { use super::runtime_types; pub struct ConstantsApi; impl ConstantsApi { - #[doc = " Pallet's weight info"] pub fn initial_difficulty( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< @@ -5558,22 +5699,6 @@ pub mod api { ], ) } - pub fn difficulty_adjust_percent_clamp( - &self, - ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< - runtime_types::sp_arithmetic::fixed_point::FixedU128, - > { - ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( - "QPoW", - "DifficultyAdjustPercentClamp", - [ - 62u8, 145u8, 102u8, 227u8, 159u8, 92u8, 27u8, 54u8, 159u8, 228u8, - 193u8, 99u8, 75u8, 196u8, 26u8, 250u8, 229u8, 230u8, 88u8, 109u8, - 246u8, 100u8, 152u8, 158u8, 14u8, 25u8, 224u8, 173u8, 224u8, 41u8, - 105u8, 231u8, - ], - ) - } pub fn target_block_time( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< @@ -5590,23 +5715,6 @@ pub mod api { ], ) } - #[doc = " EMA smoothing factor (0-1000, where 1000 = 1.0)"] - pub fn ema_alpha( - &self, - ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< - ::core::primitive::u32, - > { - ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( - "QPoW", - "EmaAlpha", - [ - 98u8, 252u8, 116u8, 72u8, 26u8, 180u8, 225u8, 83u8, 200u8, 157u8, - 125u8, 151u8, 53u8, 76u8, 168u8, 26u8, 10u8, 9u8, 98u8, 68u8, 9u8, - 178u8, 197u8, 113u8, 31u8, 79u8, 200u8, 90u8, 203u8, 100u8, 41u8, - 145u8, - ], - ) - } pub fn max_reorg_depth( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< @@ -6506,6 +6614,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] pub struct SetRetry { pub task: set_retry::Task, pub retries: set_retry::Retries, @@ -6552,6 +6664,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] pub struct SetRetryNamed { pub id: set_retry_named::Id, pub retries: set_retry_named::Retries, @@ -6640,9 +6756,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 209u8, 44u8, 38u8, 115u8, 192u8, 245u8, 230u8, 98u8, 4u8, 221u8, 48u8, - 218u8, 180u8, 45u8, 205u8, 242u8, 98u8, 60u8, 73u8, 209u8, 152u8, - 217u8, 39u8, 90u8, 46u8, 7u8, 50u8, 50u8, 214u8, 210u8, 178u8, 180u8, + 111u8, 246u8, 131u8, 153u8, 188u8, 35u8, 82u8, 23u8, 214u8, 245u8, + 97u8, 204u8, 130u8, 160u8, 102u8, 24u8, 208u8, 65u8, 222u8, 33u8, 61u8, + 120u8, 183u8, 187u8, 133u8, 232u8, 75u8, 78u8, 207u8, 123u8, 219u8, + 114u8, ], ) } @@ -6681,9 +6798,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 168u8, 23u8, 39u8, 121u8, 55u8, 131u8, 250u8, 35u8, 37u8, 194u8, 185u8, - 120u8, 150u8, 83u8, 251u8, 46u8, 33u8, 65u8, 144u8, 38u8, 77u8, 195u8, - 178u8, 91u8, 237u8, 254u8, 91u8, 211u8, 168u8, 181u8, 160u8, 137u8, + 226u8, 121u8, 55u8, 244u8, 180u8, 161u8, 195u8, 247u8, 4u8, 191u8, + 152u8, 109u8, 162u8, 105u8, 232u8, 241u8, 102u8, 3u8, 254u8, 58u8, + 224u8, 63u8, 127u8, 155u8, 66u8, 214u8, 20u8, 84u8, 200u8, 83u8, 252u8, + 190u8, ], ) } @@ -6719,9 +6837,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 72u8, 139u8, 81u8, 86u8, 46u8, 244u8, 58u8, 159u8, 117u8, 243u8, 134u8, - 98u8, 80u8, 240u8, 110u8, 81u8, 213u8, 76u8, 158u8, 96u8, 72u8, 193u8, - 249u8, 80u8, 251u8, 116u8, 166u8, 73u8, 81u8, 215u8, 75u8, 220u8, + 223u8, 138u8, 95u8, 57u8, 29u8, 157u8, 241u8, 124u8, 62u8, 169u8, + 220u8, 166u8, 67u8, 105u8, 102u8, 78u8, 138u8, 29u8, 181u8, 87u8, + 236u8, 124u8, 237u8, 245u8, 85u8, 132u8, 168u8, 95u8, 130u8, 64u8, 9u8, + 200u8, ], ) } @@ -6743,9 +6862,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 79u8, 224u8, 38u8, 251u8, 249u8, 207u8, 215u8, 115u8, 81u8, 65u8, 63u8, - 214u8, 84u8, 8u8, 50u8, 37u8, 55u8, 55u8, 61u8, 128u8, 25u8, 111u8, - 143u8, 130u8, 144u8, 164u8, 26u8, 145u8, 105u8, 180u8, 88u8, 94u8, + 15u8, 107u8, 235u8, 231u8, 115u8, 180u8, 199u8, 243u8, 222u8, 191u8, + 192u8, 130u8, 107u8, 253u8, 77u8, 228u8, 151u8, 60u8, 176u8, 69u8, + 140u8, 120u8, 110u8, 242u8, 63u8, 35u8, 46u8, 210u8, 21u8, 83u8, 8u8, + 123u8, ], ) } @@ -6760,6 +6880,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] pub fn set_retry( &self, task: types::set_retry::Task, @@ -6788,6 +6912,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] pub fn set_retry_named( &self, id: types::set_retry_named::Id, @@ -7740,9 +7868,9 @@ pub mod api { "batch", types::Batch { calls }, [ - 241u8, 24u8, 68u8, 209u8, 219u8, 28u8, 161u8, 192u8, 127u8, 101u8, - 153u8, 143u8, 78u8, 9u8, 24u8, 122u8, 110u8, 250u8, 63u8, 159u8, 174u8, - 88u8, 85u8, 23u8, 195u8, 141u8, 225u8, 43u8, 138u8, 241u8, 44u8, 111u8, + 168u8, 153u8, 140u8, 127u8, 49u8, 58u8, 84u8, 232u8, 97u8, 32u8, 62u8, + 214u8, 148u8, 56u8, 117u8, 185u8, 158u8, 13u8, 116u8, 44u8, 227u8, + 64u8, 247u8, 216u8, 184u8, 41u8, 4u8, 163u8, 162u8, 77u8, 134u8, 234u8, ], ) } @@ -7772,9 +7900,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 165u8, 80u8, 171u8, 13u8, 254u8, 5u8, 209u8, 126u8, 47u8, 137u8, 90u8, - 96u8, 227u8, 196u8, 159u8, 55u8, 118u8, 49u8, 178u8, 50u8, 178u8, 34u8, - 131u8, 3u8, 41u8, 245u8, 119u8, 197u8, 221u8, 20u8, 174u8, 102u8, + 221u8, 169u8, 48u8, 6u8, 24u8, 30u8, 152u8, 227u8, 141u8, 56u8, 160u8, + 66u8, 148u8, 225u8, 88u8, 225u8, 102u8, 31u8, 140u8, 98u8, 159u8, + 240u8, 185u8, 45u8, 110u8, 180u8, 70u8, 228u8, 109u8, 205u8, 73u8, + 42u8, ], ) } @@ -7800,9 +7929,10 @@ pub mod api { "batch_all", types::BatchAll { calls }, [ - 96u8, 62u8, 146u8, 237u8, 252u8, 60u8, 1u8, 202u8, 235u8, 81u8, 106u8, - 115u8, 226u8, 96u8, 214u8, 188u8, 216u8, 173u8, 83u8, 15u8, 78u8, 97u8, - 158u8, 66u8, 225u8, 63u8, 117u8, 196u8, 242u8, 185u8, 28u8, 145u8, + 61u8, 221u8, 247u8, 197u8, 198u8, 93u8, 227u8, 27u8, 130u8, 66u8, + 147u8, 239u8, 234u8, 219u8, 242u8, 109u8, 220u8, 4u8, 251u8, 147u8, + 86u8, 37u8, 232u8, 40u8, 208u8, 222u8, 123u8, 72u8, 1u8, 48u8, 39u8, + 252u8, ], ) } @@ -7825,10 +7955,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 47u8, 109u8, 230u8, 121u8, 146u8, 49u8, 97u8, 31u8, 138u8, 224u8, - 206u8, 114u8, 57u8, 169u8, 75u8, 158u8, 2u8, 183u8, 138u8, 243u8, - 116u8, 32u8, 225u8, 61u8, 124u8, 106u8, 167u8, 238u8, 236u8, 20u8, - 202u8, 50u8, + 211u8, 86u8, 167u8, 189u8, 24u8, 103u8, 83u8, 11u8, 102u8, 251u8, + 156u8, 78u8, 99u8, 174u8, 1u8, 90u8, 37u8, 195u8, 61u8, 102u8, 77u8, + 216u8, 136u8, 168u8, 76u8, 234u8, 228u8, 234u8, 98u8, 146u8, 246u8, + 3u8, ], ) } @@ -7854,10 +7984,9 @@ pub mod api { "force_batch", types::ForceBatch { calls }, [ - 59u8, 222u8, 239u8, 78u8, 48u8, 183u8, 141u8, 107u8, 147u8, 104u8, - 49u8, 128u8, 119u8, 239u8, 68u8, 174u8, 68u8, 200u8, 166u8, 210u8, - 70u8, 69u8, 239u8, 174u8, 193u8, 143u8, 14u8, 45u8, 194u8, 153u8, - 198u8, 118u8, + 146u8, 12u8, 37u8, 67u8, 116u8, 89u8, 65u8, 39u8, 146u8, 69u8, 186u8, + 21u8, 192u8, 211u8, 148u8, 137u8, 201u8, 3u8, 195u8, 90u8, 80u8, 57u8, + 116u8, 148u8, 29u8, 225u8, 149u8, 117u8, 185u8, 193u8, 159u8, 219u8, ], ) } @@ -7880,9 +8009,9 @@ pub mod api { weight, }, [ - 86u8, 251u8, 42u8, 213u8, 7u8, 59u8, 69u8, 56u8, 170u8, 21u8, 184u8, - 32u8, 192u8, 34u8, 250u8, 122u8, 236u8, 31u8, 174u8, 104u8, 80u8, - 255u8, 209u8, 64u8, 251u8, 39u8, 162u8, 198u8, 163u8, 61u8, 73u8, 91u8, + 108u8, 240u8, 32u8, 97u8, 18u8, 61u8, 34u8, 62u8, 149u8, 244u8, 16u8, + 87u8, 60u8, 116u8, 221u8, 156u8, 68u8, 51u8, 60u8, 233u8, 15u8, 160u8, + 180u8, 31u8, 197u8, 161u8, 165u8, 93u8, 238u8, 184u8, 50u8, 36u8, ], ) } @@ -7922,9 +8051,9 @@ pub mod api { fallback: ::subxt::ext::subxt_core::alloc::boxed::Box::new(fallback), }, [ - 63u8, 128u8, 67u8, 20u8, 83u8, 111u8, 204u8, 20u8, 153u8, 162u8, 212u8, - 42u8, 117u8, 96u8, 212u8, 248u8, 70u8, 189u8, 85u8, 158u8, 136u8, - 110u8, 142u8, 61u8, 39u8, 54u8, 195u8, 118u8, 241u8, 6u8, 55u8, 130u8, + 160u8, 250u8, 232u8, 179u8, 142u8, 199u8, 97u8, 214u8, 128u8, 114u8, + 165u8, 161u8, 57u8, 210u8, 171u8, 46u8, 89u8, 202u8, 250u8, 19u8, 45u8, + 144u8, 223u8, 4u8, 145u8, 157u8, 184u8, 228u8, 250u8, 221u8, 6u8, 5u8, ], ) } @@ -7947,9 +8076,10 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 167u8, 171u8, 21u8, 97u8, 73u8, 57u8, 83u8, 87u8, 141u8, 218u8, 49u8, - 79u8, 243u8, 165u8, 230u8, 26u8, 227u8, 116u8, 81u8, 203u8, 246u8, - 196u8, 209u8, 183u8, 16u8, 236u8, 9u8, 87u8, 169u8, 76u8, 73u8, 46u8, + 138u8, 211u8, 58u8, 120u8, 90u8, 178u8, 167u8, 166u8, 163u8, 135u8, + 34u8, 41u8, 124u8, 179u8, 160u8, 200u8, 137u8, 21u8, 36u8, 100u8, + 126u8, 66u8, 89u8, 124u8, 51u8, 155u8, 197u8, 173u8, 126u8, 1u8, 10u8, + 66u8, ], ) } @@ -9393,19 +9523,38 @@ pub mod api { #[doc = "Enable high-security for the calling account with a specified"] #[doc = "reversibility delay."] #[doc = ""] - #[doc = "Recoverer and interceptor (aka guardian) could be the same account or"] - #[doc = "different accounts."] - #[doc = ""] #[doc = "Once an account is set as high security it can only make reversible"] #[doc = "transfers. It is not allowed any other calls."] #[doc = ""] - #[doc = "- `delay`: The reversibility time for any transfer made by the high"] - #[doc = "security account."] - #[doc = "- interceptor: The account that can intercept transctions from the"] - #[doc = "high security account."] + #[doc = "# Warning: Permanent and Irreversible"] + #[doc = ""] + #[doc = "**Enabling high security mode is a one-way operation that cannot be undone.**"] + #[doc = ""] + #[doc = "Once this function is called successfully, the account is permanently restricted"] + #[doc = "to only the following operations:"] + #[doc = "- [`schedule_transfer`](Self::schedule_transfer) - Schedule delayed native token"] + #[doc = " transfers"] + #[doc = "- [`schedule_asset_transfer`](Self::schedule_asset_transfer) - Schedule delayed asset"] + #[doc = " transfers"] + #[doc = "- [`cancel`](Self::cancel) - Cancel pending transfers"] + #[doc = "- [`recover_funds`](Self::recover_funds) - Guardian-initiated emergency fund recovery"] + #[doc = ""] + #[doc = "There is no mechanism to disable high security mode or restore normal account"] + #[doc = "functionality. This design is intentional to provide maximum security guarantees:"] + #[doc = "an attacker who gains access to the account cannot simply disable the protections."] + #[doc = ""] + #[doc = "Users who no longer wish to use high-security features can simply transfer their"] + #[doc = "funds to a different account using [`schedule_transfer`](Self::schedule_transfer)"] + #[doc = "or [`schedule_asset_transfer`](Self::schedule_asset_transfer)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `delay`: The reversibility time for any transfer made by the high-security account."] + #[doc = "- `guardian`: The guardian account that can cancel pending transfers and recover funds"] + #[doc = " from this high-security account."] pub struct SetHighSecurity { pub delay: set_high_security::Delay, - pub interceptor: set_high_security::Interceptor, + pub guardian: set_high_security::Guardian, } pub mod set_high_security { use super::runtime_types; @@ -9413,7 +9562,7 @@ pub mod api { ::core::primitive::u32, ::core::primitive::u64, >; - pub type Interceptor = ::subxt::ext::subxt_core::utils::AccountId32; + pub type Guardian = ::subxt::ext::subxt_core::utils::AccountId32; } impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for SetHighSecurity { const PALLET: &'static str = "ReversibleTransfers"; @@ -9455,9 +9604,22 @@ pub mod api { #[encode_as_type( crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" )] - #[doc = "Called by the Scheduler to finalize the scheduled task/call"] + #[doc = "Executes a previously scheduled transfer after the delay period has elapsed."] + #[doc = ""] + #[doc = "This extrinsic is called automatically by the Scheduler pallet when the"] + #[doc = "delay period expires. It must be signed by this pallet's account (not a user)."] + #[doc = "The pallet account is set as the origin when scheduling via"] + #[doc = "[`do_schedule_transfer_inner`](Self::do_schedule_transfer_inner)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `tx_id`: The unique identifier of the pending transfer to execute."] + #[doc = ""] + #[doc = "# Errors"] #[doc = ""] - #[doc = "- `tx_id`: The unique id of the transaction to finalize and dispatch."] + #[doc = "- [`InvalidSchedulerOrigin`](Error::InvalidSchedulerOrigin): Called by an account other"] + #[doc = " than this pallet's account."] + #[doc = "- [`PendingTxNotFound`](Error::PendingTxNotFound): No pending transfer with this ID."] pub struct ExecuteTransfer { pub tx_id: execute_transfer::TxId, } @@ -9612,12 +9774,16 @@ pub mod api { #[encode_as_type( crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" )] - #[doc = "Allows the guardian (interceptor) to recover all funds from a high security"] - #[doc = "account by transferring the entire balance to themselves."] + #[doc = "Allows the guardian to recover all funds from a high-security account"] + #[doc = "by transferring the entire balance to themselves."] #[doc = ""] - #[doc = "This is an emergency function for when the high security account may be compromised."] + #[doc = "This is an emergency function for when the high-security account may be compromised."] #[doc = "It cancels all pending transfers first (applying volume fees), then transfers"] #[doc = "the remaining free balance to the guardian."] + #[doc = ""] + #[doc = "If releasing held funds fails for any transfer, that transfer is skipped (metadata"] + #[doc = "preserved for manual retry via `cancel`) and a `TransferRecoveryFailed` event is"] + #[doc = "emitted. Other transfers continue to be processed."] pub struct RecoverFunds { pub account: recover_funds::Account, } @@ -9635,30 +9801,49 @@ pub mod api { #[doc = "Enable high-security for the calling account with a specified"] #[doc = "reversibility delay."] #[doc = ""] - #[doc = "Recoverer and interceptor (aka guardian) could be the same account or"] - #[doc = "different accounts."] - #[doc = ""] #[doc = "Once an account is set as high security it can only make reversible"] #[doc = "transfers. It is not allowed any other calls."] #[doc = ""] - #[doc = "- `delay`: The reversibility time for any transfer made by the high"] - #[doc = "security account."] - #[doc = "- interceptor: The account that can intercept transctions from the"] - #[doc = "high security account."] + #[doc = "# Warning: Permanent and Irreversible"] + #[doc = ""] + #[doc = "**Enabling high security mode is a one-way operation that cannot be undone.**"] + #[doc = ""] + #[doc = "Once this function is called successfully, the account is permanently restricted"] + #[doc = "to only the following operations:"] + #[doc = "- [`schedule_transfer`](Self::schedule_transfer) - Schedule delayed native token"] + #[doc = " transfers"] + #[doc = "- [`schedule_asset_transfer`](Self::schedule_asset_transfer) - Schedule delayed asset"] + #[doc = " transfers"] + #[doc = "- [`cancel`](Self::cancel) - Cancel pending transfers"] + #[doc = "- [`recover_funds`](Self::recover_funds) - Guardian-initiated emergency fund recovery"] + #[doc = ""] + #[doc = "There is no mechanism to disable high security mode or restore normal account"] + #[doc = "functionality. This design is intentional to provide maximum security guarantees:"] + #[doc = "an attacker who gains access to the account cannot simply disable the protections."] + #[doc = ""] + #[doc = "Users who no longer wish to use high-security features can simply transfer their"] + #[doc = "funds to a different account using [`schedule_transfer`](Self::schedule_transfer)"] + #[doc = "or [`schedule_asset_transfer`](Self::schedule_asset_transfer)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `delay`: The reversibility time for any transfer made by the high-security account."] + #[doc = "- `guardian`: The guardian account that can cancel pending transfers and recover funds"] + #[doc = " from this high-security account."] pub fn set_high_security( &self, delay: types::set_high_security::Delay, - interceptor: types::set_high_security::Interceptor, + guardian: types::set_high_security::Guardian, ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload { ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( "ReversibleTransfers", "set_high_security", - types::SetHighSecurity { delay, interceptor }, + types::SetHighSecurity { delay, guardian }, [ - 202u8, 17u8, 43u8, 37u8, 215u8, 198u8, 42u8, 183u8, 53u8, 124u8, 140u8, - 34u8, 112u8, 230u8, 55u8, 168u8, 242u8, 249u8, 91u8, 185u8, 244u8, - 81u8, 40u8, 231u8, 121u8, 155u8, 202u8, 76u8, 137u8, 7u8, 225u8, 184u8, + 103u8, 202u8, 28u8, 11u8, 249u8, 80u8, 142u8, 200u8, 55u8, 4u8, 141u8, + 72u8, 94u8, 199u8, 229u8, 102u8, 246u8, 113u8, 190u8, 84u8, 95u8, + 193u8, 96u8, 171u8, 144u8, 120u8, 235u8, 208u8, 65u8, 183u8, 4u8, 44u8, ], ) } @@ -9681,9 +9866,22 @@ pub mod api { ], ) } - #[doc = "Called by the Scheduler to finalize the scheduled task/call"] + #[doc = "Executes a previously scheduled transfer after the delay period has elapsed."] #[doc = ""] - #[doc = "- `tx_id`: The unique id of the transaction to finalize and dispatch."] + #[doc = "This extrinsic is called automatically by the Scheduler pallet when the"] + #[doc = "delay period expires. It must be signed by this pallet's account (not a user)."] + #[doc = "The pallet account is set as the origin when scheduling via"] + #[doc = "[`do_schedule_transfer_inner`](Self::do_schedule_transfer_inner)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `tx_id`: The unique identifier of the pending transfer to execute."] + #[doc = ""] + #[doc = "# Errors"] + #[doc = ""] + #[doc = "- [`InvalidSchedulerOrigin`](Error::InvalidSchedulerOrigin): Called by an account other"] + #[doc = " than this pallet's account."] + #[doc = "- [`PendingTxNotFound`](Error::PendingTxNotFound): No pending transfer with this ID."] pub fn execute_transfer( &self, tx_id: types::execute_transfer::TxId, @@ -9788,12 +9986,16 @@ pub mod api { ], ) } - #[doc = "Allows the guardian (interceptor) to recover all funds from a high security"] - #[doc = "account by transferring the entire balance to themselves."] + #[doc = "Allows the guardian to recover all funds from a high-security account"] + #[doc = "by transferring the entire balance to themselves."] #[doc = ""] - #[doc = "This is an emergency function for when the high security account may be compromised."] + #[doc = "This is an emergency function for when the high-security account may be compromised."] #[doc = "It cancels all pending transfers first (applying volume fees), then transfers"] #[doc = "the remaining free balance to the guardian."] + #[doc = ""] + #[doc = "If releasing held funds fails for any transfer, that transfer is skipped (metadata"] + #[doc = "preserved for manual retry via `cancel`) and a `TransferRecoveryFailed` event is"] + #[doc = "emitted. Other transfers continue to be processed."] pub fn recover_funds( &self, account: types::recover_funds::Account, @@ -9824,16 +10026,15 @@ pub mod api { #[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 = "A user has enabled their high-security settings."] - #[doc = "[who, interceptor, recoverer, delay]"] pub struct HighSecuritySet { pub who: high_security_set::Who, - pub interceptor: high_security_set::Interceptor, + pub guardian: high_security_set::Guardian, pub delay: high_security_set::Delay, } pub mod high_security_set { use super::runtime_types; pub type Who = ::subxt::ext::subxt_core::utils::AccountId32; - pub type Interceptor = ::subxt::ext::subxt_core::utils::AccountId32; + pub type Guardian = ::subxt::ext::subxt_core::utils::AccountId32; pub type Delay = runtime_types::qp_scheduler::BlockNumberOrTimestamp< ::core::primitive::u32, ::core::primitive::u64, @@ -9850,12 +10051,11 @@ pub mod api { )] #[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 = "A transaction has been intercepted and scheduled for delayed execution."] - #[doc = "[from, to, interceptor, amount, tx_id, execute_at_moment]"] + #[doc = "A transaction has been scheduled for delayed execution."] pub struct TransactionScheduled { pub from: transaction_scheduled::From, pub to: transaction_scheduled::To, - pub interceptor: transaction_scheduled::Interceptor, + pub guardian: transaction_scheduled::Guardian, pub asset_id: transaction_scheduled::AssetId, pub amount: transaction_scheduled::Amount, pub tx_id: transaction_scheduled::TxId, @@ -9865,7 +10065,7 @@ pub mod api { use super::runtime_types; pub type From = ::subxt::ext::subxt_core::utils::AccountId32; pub type To = ::subxt::ext::subxt_core::utils::AccountId32; - pub type Interceptor = ::subxt::ext::subxt_core::utils::AccountId32; + pub type Guardian = ::subxt::ext::subxt_core::utils::AccountId32; pub type AssetId = ::core::option::Option<::core::primitive::u32>; pub type Amount = ::core::primitive::u128; pub type TxId = ::subxt::ext::subxt_core::utils::H256; @@ -9885,7 +10085,7 @@ pub mod api { )] #[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 = "A scheduled transaction has been successfully cancelled by the owner."] + #[doc = "A scheduled transaction has been successfully cancelled."] pub struct TransactionCancelled { pub who: transaction_cancelled::Who, pub tx_id: transaction_cancelled::TxId, @@ -9932,7 +10132,7 @@ pub mod api { )] #[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 = "Funds were recovered from a high security account by its guardian."] + #[doc = "All funds were recovered from a high-security account by its guardian."] pub struct FundsRecovered { pub account: funds_recovered::Account, pub guardian: funds_recovered::Guardian, @@ -9946,6 +10146,26 @@ pub mod api { const PALLET: &'static str = "ReversibleTransfers"; const EVENT: &'static str = "FundsRecovered"; } + #[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 = "Failed to release held funds during recovery. The transfer metadata is preserved"] + #[doc = "for manual retry via `cancel`."] + pub struct TransferRecoveryFailed { + pub tx_id: transfer_recovery_failed::TxId, + } + pub mod transfer_recovery_failed { + use super::runtime_types; + pub type TxId = ::subxt::ext::subxt_core::utils::H256; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for TransferRecoveryFailed { + const PALLET: &'static str = "ReversibleTransfers"; + const EVENT: &'static str = "TransferRecoveryFailed"; + } } pub mod storage { use super::runtime_types; @@ -9969,10 +10189,7 @@ pub mod api { runtime_types::pallet_reversible_transfers::PendingTransfer< ::subxt::ext::subxt_core::utils::AccountId32, ::core::primitive::u128, - runtime_types::frame_support::traits::preimages::Bounded< - runtime_types::quantus_runtime::RuntimeCall, - runtime_types::sp_runtime::traits::BlakeTwo256, - >, + ::core::primitive::u32, >; pub type Param0 = ::subxt::ext::subxt_core::utils::H256; } @@ -9984,17 +10201,17 @@ pub mod api { >; pub type Param0 = ::subxt::ext::subxt_core::utils::AccountId32; } - pub mod interceptor_index { + pub mod guardian_index { use super::runtime_types; - pub type InterceptorIndex = + pub type GuardianIndex = runtime_types::bounded_collections::bounded_vec::BoundedVec< ::subxt::ext::subxt_core::utils::AccountId32, >; pub type Param0 = ::subxt::ext::subxt_core::utils::AccountId32; } - pub mod global_nonce { + pub mod next_transaction_id { use super::runtime_types; - pub type GlobalNonce = ::core::primitive::u64; + pub type NextTransactionId = ::core::primitive::u64; } } pub struct StorageApi; @@ -10015,10 +10232,10 @@ pub mod api { "HighSecurityAccounts", (), [ - 11u8, 143u8, 95u8, 23u8, 55u8, 163u8, 22u8, 238u8, 88u8, 24u8, 50u8, - 162u8, 72u8, 98u8, 32u8, 219u8, 231u8, 199u8, 118u8, 150u8, 84u8, - 126u8, 225u8, 88u8, 129u8, 200u8, 236u8, 214u8, 187u8, 8u8, 252u8, - 120u8, + 110u8, 63u8, 150u8, 254u8, 213u8, 163u8, 141u8, 156u8, 66u8, 201u8, + 162u8, 30u8, 141u8, 204u8, 209u8, 159u8, 120u8, 240u8, 230u8, 239u8, + 228u8, 129u8, 130u8, 181u8, 6u8, 193u8, 157u8, 239u8, 131u8, 35u8, + 29u8, 79u8, ], ) } @@ -10041,10 +10258,10 @@ pub mod api { "HighSecurityAccounts", ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), [ - 11u8, 143u8, 95u8, 23u8, 55u8, 163u8, 22u8, 238u8, 88u8, 24u8, 50u8, - 162u8, 72u8, 98u8, 32u8, 219u8, 231u8, 199u8, 118u8, 150u8, 84u8, - 126u8, 225u8, 88u8, 129u8, 200u8, 236u8, 214u8, 187u8, 8u8, 252u8, - 120u8, + 110u8, 63u8, 150u8, 254u8, 213u8, 163u8, 141u8, 156u8, 66u8, 201u8, + 162u8, 30u8, 141u8, 204u8, 209u8, 159u8, 120u8, 240u8, 230u8, 239u8, + 228u8, 129u8, 130u8, 181u8, 6u8, 193u8, 157u8, 239u8, 131u8, 35u8, + 29u8, 79u8, ], ) } @@ -10064,9 +10281,10 @@ pub mod api { "PendingTransfers", (), [ - 226u8, 148u8, 100u8, 60u8, 9u8, 160u8, 164u8, 177u8, 53u8, 236u8, 65u8, - 38u8, 207u8, 31u8, 170u8, 79u8, 15u8, 237u8, 127u8, 189u8, 203u8, - 147u8, 4u8, 146u8, 13u8, 87u8, 158u8, 163u8, 159u8, 87u8, 98u8, 211u8, + 138u8, 155u8, 227u8, 133u8, 16u8, 122u8, 128u8, 60u8, 245u8, 159u8, + 244u8, 82u8, 244u8, 113u8, 189u8, 149u8, 179u8, 30u8, 48u8, 31u8, + 174u8, 124u8, 28u8, 33u8, 190u8, 217u8, 193u8, 129u8, 39u8, 122u8, + 141u8, 188u8, ], ) } @@ -10089,9 +10307,10 @@ pub mod api { "PendingTransfers", ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), [ - 226u8, 148u8, 100u8, 60u8, 9u8, 160u8, 164u8, 177u8, 53u8, 236u8, 65u8, - 38u8, 207u8, 31u8, 170u8, 79u8, 15u8, 237u8, 127u8, 189u8, 203u8, - 147u8, 4u8, 146u8, 13u8, 87u8, 158u8, 163u8, 159u8, 87u8, 98u8, 211u8, + 138u8, 155u8, 227u8, 133u8, 16u8, 122u8, 128u8, 60u8, 245u8, 159u8, + 244u8, 82u8, 244u8, 113u8, 189u8, 149u8, 179u8, 30u8, 48u8, 31u8, + 174u8, 124u8, 28u8, 33u8, 190u8, 217u8, 193u8, 129u8, 39u8, 122u8, + 141u8, 188u8, ], ) } @@ -10140,75 +10359,78 @@ pub mod api { ], ) } - #[doc = " Maps interceptor accounts to the list of accounts they can intercept for."] - #[doc = " This allows the UI to efficiently query all accounts for which a given account is an"] - #[doc = " interceptor."] - pub fn interceptor_index_iter( + #[doc = " Maps guardian accounts to the list of accounts they protect."] + #[doc = " This allows the UI to efficiently query all accounts for which a given account is a"] + #[doc = " guardian."] + pub fn guardian_index_iter( &self, ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< (), - types::interceptor_index::InterceptorIndex, + types::guardian_index::GuardianIndex, (), ::subxt::ext::subxt_core::utils::Yes, ::subxt::ext::subxt_core::utils::Yes, > { ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( "ReversibleTransfers", - "InterceptorIndex", + "GuardianIndex", (), [ - 7u8, 184u8, 75u8, 107u8, 42u8, 84u8, 188u8, 86u8, 2u8, 227u8, 4u8, - 136u8, 109u8, 69u8, 64u8, 123u8, 253u8, 28u8, 174u8, 121u8, 183u8, - 154u8, 135u8, 91u8, 125u8, 0u8, 58u8, 132u8, 164u8, 236u8, 182u8, - 133u8, + 112u8, 32u8, 227u8, 175u8, 221u8, 116u8, 83u8, 105u8, 108u8, 132u8, + 254u8, 61u8, 178u8, 251u8, 179u8, 127u8, 14u8, 12u8, 144u8, 204u8, + 38u8, 98u8, 154u8, 10u8, 202u8, 254u8, 230u8, 126u8, 149u8, 161u8, + 13u8, 110u8, ], ) } - #[doc = " Maps interceptor accounts to the list of accounts they can intercept for."] - #[doc = " This allows the UI to efficiently query all accounts for which a given account is an"] - #[doc = " interceptor."] - pub fn interceptor_index( + #[doc = " Maps guardian accounts to the list of accounts they protect."] + #[doc = " This allows the UI to efficiently query all accounts for which a given account is a"] + #[doc = " guardian."] + pub fn guardian_index( &self, - _0: types::interceptor_index::Param0, + _0: types::guardian_index::Param0, ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< ::subxt::ext::subxt_core::storage::address::StaticStorageKey< - types::interceptor_index::Param0, + types::guardian_index::Param0, >, - types::interceptor_index::InterceptorIndex, + types::guardian_index::GuardianIndex, ::subxt::ext::subxt_core::utils::Yes, ::subxt::ext::subxt_core::utils::Yes, (), > { ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( "ReversibleTransfers", - "InterceptorIndex", + "GuardianIndex", ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), [ - 7u8, 184u8, 75u8, 107u8, 42u8, 84u8, 188u8, 86u8, 2u8, 227u8, 4u8, - 136u8, 109u8, 69u8, 64u8, 123u8, 253u8, 28u8, 174u8, 121u8, 183u8, - 154u8, 135u8, 91u8, 125u8, 0u8, 58u8, 132u8, 164u8, 236u8, 182u8, - 133u8, + 112u8, 32u8, 227u8, 175u8, 221u8, 116u8, 83u8, 105u8, 108u8, 132u8, + 254u8, 61u8, 178u8, 251u8, 179u8, 127u8, 14u8, 12u8, 144u8, 204u8, + 38u8, 98u8, 154u8, 10u8, 202u8, 254u8, 230u8, 126u8, 149u8, 161u8, + 13u8, 110u8, ], ) } - #[doc = " Global nonce for generating unique transaction IDs."] - pub fn global_nonce( + #[doc = " Monotonically increasing counter used to generate unique transaction IDs."] + #[doc = " Each scheduled transfer increments this value to ensure no two transfers"] + #[doc = " produce the same `tx_id`, even if they have identical parameters."] + pub fn next_transaction_id( &self, ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< (), - types::global_nonce::GlobalNonce, + types::next_transaction_id::NextTransactionId, ::subxt::ext::subxt_core::utils::Yes, ::subxt::ext::subxt_core::utils::Yes, (), > { ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( "ReversibleTransfers", - "GlobalNonce", + "NextTransactionId", (), [ - 119u8, 119u8, 84u8, 141u8, 83u8, 67u8, 42u8, 83u8, 51u8, 196u8, 185u8, - 39u8, 227u8, 125u8, 142u8, 154u8, 107u8, 62u8, 127u8, 13u8, 54u8, - 114u8, 201u8, 6u8, 100u8, 28u8, 202u8, 152u8, 246u8, 202u8, 9u8, 29u8, + 42u8, 56u8, 195u8, 140u8, 101u8, 56u8, 175u8, 152u8, 210u8, 167u8, + 61u8, 134u8, 152u8, 191u8, 216u8, 58u8, 73u8, 109u8, 130u8, 125u8, + 189u8, 186u8, 142u8, 68u8, 222u8, 141u8, 16u8, 250u8, 85u8, 8u8, 196u8, + 188u8, ], ) } @@ -10218,15 +10440,15 @@ pub mod api { use super::runtime_types; pub struct ConstantsApi; impl ConstantsApi { - #[doc = " Maximum number of accounts an interceptor can intercept for. Used for BoundedVec."] - pub fn max_interceptor_accounts( + #[doc = " Maximum number of accounts a single guardian can protect. Used for BoundedVec."] + pub fn max_guardian_accounts( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< ::core::primitive::u32, > { ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( "ReversibleTransfers", - "MaxInterceptorAccounts", + "MaxGuardianAccounts", [ 98u8, 252u8, 116u8, 72u8, 26u8, 180u8, 225u8, 83u8, 200u8, 157u8, 125u8, 151u8, 53u8, 76u8, 168u8, 26u8, 10u8, 9u8, 98u8, 68u8, 9u8, @@ -13353,6 +13575,11 @@ pub mod api { crate_path = ":: subxt :: ext :: subxt_core :: ext :: scale_encode" )] #[doc = "Set the treasury account. Root only. Zero address is rejected (funds would be locked)."] + #[doc = ""] + #[doc = "**Important**: This only changes where *future* mining rewards are sent. Any balance"] + #[doc = "that has already accumulated in the current treasury account is NOT automatically"] + #[doc = "migrated to the new account. If you need to move existing funds, perform a separate"] + #[doc = "balance transfer (e.g., via governance proposal) after updating the account."] pub struct SetTreasuryAccount { pub account: set_treasury_account::Account, } @@ -13391,6 +13618,11 @@ pub mod api { pub struct TransactionApi; impl TransactionApi { #[doc = "Set the treasury account. Root only. Zero address is rejected (funds would be locked)."] + #[doc = ""] + #[doc = "**Important**: This only changes where *future* mining rewards are sent. Any balance"] + #[doc = "that has already accumulated in the current treasury account is NOT automatically"] + #[doc = "migrated to the new account. If you need to move existing funds, perform a separate"] + #[doc = "balance transfer (e.g., via governance proposal) after updating the account."] pub fn set_treasury_account( &self, account: types::set_treasury_account::Account, @@ -13438,11 +13670,19 @@ pub mod api { )] #[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 treasury account was updated."] + #[doc = ""] + #[doc = "Note: This only redirects where future mining rewards are sent. Any balance"] + #[doc = "accumulated in the old account remains there and is NOT automatically migrated."] + #[doc = "Use a separate balance transfer if funds need to be moved."] pub struct TreasuryAccountUpdated { + pub old_account: treasury_account_updated::OldAccount, pub new_account: treasury_account_updated::NewAccount, } pub mod treasury_account_updated { use super::runtime_types; + pub type OldAccount = + ::core::option::Option<::subxt::ext::subxt_core::utils::AccountId32>; pub type NewAccount = ::subxt::ext::subxt_core::utils::AccountId32; } impl ::subxt::ext::subxt_core::events::StaticEvent for TreasuryAccountUpdated { @@ -13456,6 +13696,7 @@ pub mod api { )] #[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 treasury portion (share of mining rewards) was updated."] pub struct TreasuryPortionUpdated { pub new_portion: treasury_portion_updated::NewPortion, } @@ -13939,10 +14180,9 @@ pub mod api { call: ::subxt::ext::subxt_core::alloc::boxed::Box::new(call), }, [ - 145u8, 166u8, 24u8, 188u8, 62u8, 129u8, 16u8, 49u8, 10u8, 139u8, 33u8, - 24u8, 183u8, 248u8, 92u8, 239u8, 141u8, 11u8, 109u8, 166u8, 232u8, - 206u8, 123u8, 228u8, 213u8, 173u8, 87u8, 199u8, 92u8, 239u8, 240u8, - 30u8, + 71u8, 178u8, 63u8, 91u8, 78u8, 140u8, 29u8, 153u8, 6u8, 45u8, 75u8, + 246u8, 87u8, 173u8, 86u8, 162u8, 22u8, 132u8, 34u8, 59u8, 39u8, 235u8, + 150u8, 74u8, 227u8, 47u8, 217u8, 153u8, 37u8, 164u8, 173u8, 239u8, ], ) } @@ -18866,7 +19106,6 @@ pub mod api { #[doc = ""] #[doc = "Economic costs:"] #[doc = "- MultisigFee: burned immediately (spam prevention)"] - #[doc = "- MultisigDeposit: reserved until dissolution, then returned to creator (storage bond)"] pub struct CreateMultisig { pub signers: create_multisig::Signers, pub threshold: create_multisig::Threshold, @@ -18919,8 +19158,9 @@ pub mod api { pub mod propose { use super::runtime_types; pub type MultisigAddress = ::subxt::ext::subxt_core::utils::AccountId32; - pub type Call = - ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>; + pub type Call = runtime_types::bounded_collections::bounded_vec::BoundedVec< + ::core::primitive::u8, + >; pub type Expiry = ::core::primitive::u32; } impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for Propose { @@ -19081,6 +19321,10 @@ pub mod api { #[doc = "Parameters:"] #[doc = "- `multisig_address`: The multisig account"] #[doc = "- `proposal_id`: ID (nonce) of the proposal to execute"] + #[doc = ""] + #[doc = "Note: The weight charged includes both multisig bookkeeping and MaxInnerCallWeight."] + #[doc = "Actual weight is refunded based on the inner call's post-dispatch info."] + #[doc = "The inner call's weight is validated against MaxInnerCallWeight at propose time."] pub struct Execute { pub multisig_address: execute::MultisigAddress, pub proposal_id: execute::ProposalId, @@ -19094,41 +19338,6 @@ pub mod api { const PALLET: &'static str = "Multisig"; const CALL: &'static str = "execute"; } - #[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 = "Approve dissolving a multisig account"] - #[doc = ""] - #[doc = "Signers call this to approve dissolving the multisig."] - #[doc = "When threshold is reached, the multisig is automatically dissolved."] - #[doc = ""] - #[doc = "Requirements:"] - #[doc = "- Caller must be a signer"] - #[doc = "- No proposals exist (active, executed, or cancelled) - must be fully cleaned up"] - #[doc = "- Multisig account balance must be zero"] - #[doc = ""] - #[doc = "When threshold is reached:"] - #[doc = "- Deposit is returned to creator"] - #[doc = "- Multisig storage is removed"] - pub struct ApproveDissolve { - pub multisig_address: approve_dissolve::MultisigAddress, - } - pub mod approve_dissolve { - use super::runtime_types; - pub type MultisigAddress = ::subxt::ext::subxt_core::utils::AccountId32; - } - impl ::subxt::ext::subxt_core::blocks::StaticExtrinsic for ApproveDissolve { - const PALLET: &'static str = "Multisig"; - const CALL: &'static str = "approve_dissolve"; - } } pub struct TransactionApi; impl TransactionApi { @@ -19146,7 +19355,6 @@ pub mod api { #[doc = ""] #[doc = "Economic costs:"] #[doc = "- MultisigFee: burned immediately (spam prevention)"] - #[doc = "- MultisigDeposit: reserved until dissolution, then returned to creator (storage bond)"] pub fn create_multisig( &self, signers: types::create_multisig::Signers, @@ -19193,10 +19401,10 @@ pub mod api { "propose", types::Propose { multisig_address, call, expiry }, [ - 131u8, 107u8, 67u8, 245u8, 123u8, 74u8, 248u8, 60u8, 181u8, 88u8, - 135u8, 198u8, 188u8, 160u8, 34u8, 137u8, 7u8, 126u8, 45u8, 169u8, - 212u8, 30u8, 251u8, 147u8, 167u8, 166u8, 76u8, 70u8, 155u8, 222u8, - 70u8, 143u8, + 211u8, 229u8, 94u8, 85u8, 157u8, 195u8, 92u8, 25u8, 121u8, 135u8, + 222u8, 58u8, 218u8, 102u8, 12u8, 218u8, 179u8, 96u8, 47u8, 148u8, + 236u8, 151u8, 95u8, 187u8, 170u8, 222u8, 148u8, 77u8, 136u8, 240u8, + 119u8, 67u8, ], ) } @@ -19314,6 +19522,10 @@ pub mod api { #[doc = "Parameters:"] #[doc = "- `multisig_address`: The multisig account"] #[doc = "- `proposal_id`: ID (nonce) of the proposal to execute"] + #[doc = ""] + #[doc = "Note: The weight charged includes both multisig bookkeeping and MaxInnerCallWeight."] + #[doc = "Actual weight is refunded based on the inner call's post-dispatch info."] + #[doc = "The inner call's weight is validated against MaxInnerCallWeight at propose time."] pub fn execute( &self, multisig_address: types::execute::MultisigAddress, @@ -19330,36 +19542,6 @@ pub mod api { ], ) } - #[doc = "Approve dissolving a multisig account"] - #[doc = ""] - #[doc = "Signers call this to approve dissolving the multisig."] - #[doc = "When threshold is reached, the multisig is automatically dissolved."] - #[doc = ""] - #[doc = "Requirements:"] - #[doc = "- Caller must be a signer"] - #[doc = "- No proposals exist (active, executed, or cancelled) - must be fully cleaned up"] - #[doc = "- Multisig account balance must be zero"] - #[doc = ""] - #[doc = "When threshold is reached:"] - #[doc = "- Deposit is returned to creator"] - #[doc = "- Multisig storage is removed"] - pub fn approve_dissolve( - &self, - multisig_address: types::approve_dissolve::MultisigAddress, - ) -> ::subxt::ext::subxt_core::tx::payload::StaticPayload - { - ::subxt::ext::subxt_core::tx::payload::StaticPayload::new_static( - "Multisig", - "approve_dissolve", - types::ApproveDissolve { multisig_address }, - [ - 156u8, 98u8, 164u8, 184u8, 61u8, 224u8, 117u8, 109u8, 44u8, 173u8, - 59u8, 188u8, 164u8, 233u8, 191u8, 223u8, 240u8, 203u8, 164u8, 113u8, - 184u8, 187u8, 41u8, 154u8, 87u8, 135u8, 229u8, 56u8, 35u8, 196u8, - 136u8, 241u8, - ], - ) - } } } #[doc = "The `Event` enum of this pallet"] @@ -19426,23 +19608,23 @@ pub mod api { )] #[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 = "A proposal has been approved by a signer"] - pub struct ProposalApproved { - pub multisig_address: proposal_approved::MultisigAddress, - pub approver: proposal_approved::Approver, - pub proposal_id: proposal_approved::ProposalId, - pub approvals_count: proposal_approved::ApprovalsCount, - } - pub mod proposal_approved { + #[doc = "A signer has approved a proposal (does not imply threshold reached)"] + pub struct SignerApproved { + pub multisig_address: signer_approved::MultisigAddress, + pub approver: signer_approved::Approver, + pub proposal_id: signer_approved::ProposalId, + pub approvals_count: signer_approved::ApprovalsCount, + } + pub mod signer_approved { use super::runtime_types; pub type MultisigAddress = ::subxt::ext::subxt_core::utils::AccountId32; pub type Approver = ::subxt::ext::subxt_core::utils::AccountId32; pub type ProposalId = ::core::primitive::u32; pub type ApprovalsCount = ::core::primitive::u32; } - impl ::subxt::ext::subxt_core::events::StaticEvent for ProposalApproved { + impl ::subxt::ext::subxt_core::events::StaticEvent for SignerApproved { const PALLET: &'static str = "Multisig"; - const EVENT: &'static str = "ProposalApproved"; + const EVENT: &'static str = "SignerApproved"; } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -19561,7 +19743,6 @@ pub mod api { pub claimer: deposits_claimed::Claimer, pub total_returned: deposits_claimed::TotalReturned, pub proposals_removed: deposits_claimed::ProposalsRemoved, - pub multisig_removed: deposits_claimed::MultisigRemoved, } pub mod deposits_claimed { use super::runtime_types; @@ -19569,60 +19750,11 @@ pub mod api { pub type Claimer = ::subxt::ext::subxt_core::utils::AccountId32; pub type TotalReturned = ::core::primitive::u128; pub type ProposalsRemoved = ::core::primitive::u32; - pub type MultisigRemoved = ::core::primitive::bool; } impl ::subxt::ext::subxt_core::events::StaticEvent for DepositsClaimed { const PALLET: &'static str = "Multisig"; const EVENT: &'static str = "DepositsClaimed"; } - #[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 = "A signer approved dissolving the multisig"] - pub struct DissolveApproved { - pub multisig_address: dissolve_approved::MultisigAddress, - pub approver: dissolve_approved::Approver, - pub approvals_count: dissolve_approved::ApprovalsCount, - } - pub mod dissolve_approved { - use super::runtime_types; - pub type MultisigAddress = ::subxt::ext::subxt_core::utils::AccountId32; - pub type Approver = ::subxt::ext::subxt_core::utils::AccountId32; - pub type ApprovalsCount = ::core::primitive::u32; - } - impl ::subxt::ext::subxt_core::events::StaticEvent for DissolveApproved { - const PALLET: &'static str = "Multisig"; - const EVENT: &'static str = "DissolveApproved"; - } - #[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 = "A multisig account was dissolved (threshold reached)"] - pub struct MultisigDissolved { - pub multisig_address: multisig_dissolved::MultisigAddress, - pub deposit_returned: multisig_dissolved::DepositReturned, - pub approvers: multisig_dissolved::Approvers, - } - pub mod multisig_dissolved { - use super::runtime_types; - pub type MultisigAddress = ::subxt::ext::subxt_core::utils::AccountId32; - pub type DepositReturned = ::subxt::ext::subxt_core::utils::AccountId32; - pub type Approvers = ::subxt::ext::subxt_core::alloc::vec::Vec< - ::subxt::ext::subxt_core::utils::AccountId32, - >; - } - impl ::subxt::ext::subxt_core::events::StaticEvent for MultisigDissolved { - const PALLET: &'static str = "Multisig"; - const EVENT: &'static str = "MultisigDissolved"; - } } pub mod storage { use super::runtime_types; @@ -19635,7 +19767,6 @@ pub mod api { runtime_types::bounded_collections::bounded_vec::BoundedVec< ::subxt::ext::subxt_core::utils::AccountId32, >, - ::core::primitive::u128, runtime_types::bounded_collections::bounded_btree_map::BoundedBTreeMap< ::subxt::ext::subxt_core::utils::AccountId32, ::core::primitive::u32, @@ -19659,14 +19790,6 @@ pub mod api { pub type Param0 = ::subxt::ext::subxt_core::utils::AccountId32; pub type Param1 = ::core::primitive::u32; } - pub mod dissolve_approvals { - use super::runtime_types; - pub type DissolveApprovals = - runtime_types::bounded_collections::bounded_vec::BoundedVec< - ::subxt::ext::subxt_core::utils::AccountId32, - >; - pub type Param0 = ::subxt::ext::subxt_core::utils::AccountId32; - } } pub struct StorageApi; impl StorageApi { @@ -19685,9 +19808,9 @@ pub mod api { "Multisigs", (), [ - 81u8, 182u8, 236u8, 127u8, 98u8, 244u8, 6u8, 51u8, 209u8, 6u8, 214u8, - 144u8, 49u8, 117u8, 203u8, 39u8, 180u8, 247u8, 172u8, 228u8, 72u8, - 25u8, 171u8, 55u8, 41u8, 236u8, 14u8, 135u8, 22u8, 6u8, 241u8, 230u8, + 33u8, 147u8, 123u8, 194u8, 230u8, 220u8, 119u8, 150u8, 95u8, 161u8, + 244u8, 30u8, 177u8, 39u8, 20u8, 73u8, 112u8, 15u8, 42u8, 237u8, 117u8, + 250u8, 200u8, 2u8, 0u8, 145u8, 91u8, 219u8, 8u8, 137u8, 107u8, 54u8, ], ) } @@ -19709,9 +19832,9 @@ pub mod api { "Multisigs", ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), [ - 81u8, 182u8, 236u8, 127u8, 98u8, 244u8, 6u8, 51u8, 209u8, 6u8, 214u8, - 144u8, 49u8, 117u8, 203u8, 39u8, 180u8, 247u8, 172u8, 228u8, 72u8, - 25u8, 171u8, 55u8, 41u8, 236u8, 14u8, 135u8, 22u8, 6u8, 241u8, 230u8, + 33u8, 147u8, 123u8, 194u8, 230u8, 220u8, 119u8, 150u8, 95u8, 161u8, + 244u8, 30u8, 177u8, 39u8, 20u8, 73u8, 112u8, 15u8, 42u8, 237u8, 117u8, + 250u8, 200u8, 2u8, 0u8, 145u8, 91u8, 219u8, 8u8, 137u8, 107u8, 54u8, ], ) } @@ -19730,10 +19853,9 @@ pub mod api { "Proposals", (), [ - 102u8, 10u8, 240u8, 43u8, 229u8, 237u8, 64u8, 243u8, 64u8, 7u8, 59u8, - 83u8, 229u8, 106u8, 209u8, 184u8, 240u8, 116u8, 205u8, 176u8, 4u8, - 247u8, 234u8, 87u8, 177u8, 197u8, 117u8, 38u8, 83u8, 216u8, 218u8, - 67u8, + 23u8, 150u8, 115u8, 215u8, 96u8, 175u8, 20u8, 135u8, 85u8, 106u8, 93u8, + 135u8, 139u8, 72u8, 178u8, 43u8, 130u8, 76u8, 85u8, 75u8, 74u8, 69u8, + 74u8, 232u8, 36u8, 30u8, 239u8, 26u8, 233u8, 249u8, 142u8, 163u8, ], ) } @@ -19755,10 +19877,9 @@ pub mod api { "Proposals", ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), [ - 102u8, 10u8, 240u8, 43u8, 229u8, 237u8, 64u8, 243u8, 64u8, 7u8, 59u8, - 83u8, 229u8, 106u8, 209u8, 184u8, 240u8, 116u8, 205u8, 176u8, 4u8, - 247u8, 234u8, 87u8, 177u8, 197u8, 117u8, 38u8, 83u8, 216u8, 218u8, - 67u8, + 23u8, 150u8, 115u8, 215u8, 96u8, 175u8, 20u8, 135u8, 85u8, 106u8, 93u8, + 135u8, 139u8, 72u8, 178u8, 43u8, 130u8, 76u8, 85u8, 75u8, 74u8, 69u8, + 74u8, 232u8, 36u8, 30u8, 239u8, 26u8, 233u8, 249u8, 142u8, 163u8, ], ) } @@ -19789,57 +19910,9 @@ pub mod api { ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_1), ), [ - 102u8, 10u8, 240u8, 43u8, 229u8, 237u8, 64u8, 243u8, 64u8, 7u8, 59u8, - 83u8, 229u8, 106u8, 209u8, 184u8, 240u8, 116u8, 205u8, 176u8, 4u8, - 247u8, 234u8, 87u8, 177u8, 197u8, 117u8, 38u8, 83u8, 216u8, 218u8, - 67u8, - ], - ) - } - #[doc = " Dissolve approvals: tracks which signers approved dissolving the multisig"] - #[doc = " Maps multisig_address -> Vec"] - pub fn dissolve_approvals_iter( - &self, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - (), - types::dissolve_approvals::DissolveApprovals, - (), - (), - ::subxt::ext::subxt_core::utils::Yes, - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "Multisig", - "DissolveApprovals", - (), - [ - 204u8, 17u8, 210u8, 54u8, 125u8, 128u8, 75u8, 21u8, 158u8, 13u8, 205u8, - 89u8, 98u8, 73u8, 141u8, 159u8, 53u8, 129u8, 19u8, 195u8, 2u8, 178u8, - 26u8, 137u8, 206u8, 7u8, 108u8, 196u8, 195u8, 4u8, 54u8, 111u8, - ], - ) - } - #[doc = " Dissolve approvals: tracks which signers approved dissolving the multisig"] - #[doc = " Maps multisig_address -> Vec"] - pub fn dissolve_approvals( - &self, - _0: types::dissolve_approvals::Param0, - ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< - ::subxt::ext::subxt_core::storage::address::StaticStorageKey< - types::dissolve_approvals::Param0, - >, - types::dissolve_approvals::DissolveApprovals, - ::subxt::ext::subxt_core::utils::Yes, - (), - (), - > { - ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( - "Multisig", - "DissolveApprovals", - ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), - [ - 204u8, 17u8, 210u8, 54u8, 125u8, 128u8, 75u8, 21u8, 158u8, 13u8, 205u8, - 89u8, 98u8, 73u8, 141u8, 159u8, 53u8, 129u8, 19u8, 195u8, 2u8, 178u8, - 26u8, 137u8, 206u8, 7u8, 108u8, 196u8, 195u8, 4u8, 54u8, 111u8, + 23u8, 150u8, 115u8, 215u8, 96u8, 175u8, 20u8, 135u8, 85u8, 106u8, 93u8, + 135u8, 139u8, 72u8, 178u8, 43u8, 130u8, 76u8, 85u8, 75u8, 74u8, 69u8, + 74u8, 232u8, 36u8, 30u8, 239u8, 26u8, 233u8, 249u8, 142u8, 163u8, ], ) } @@ -19866,8 +19939,9 @@ pub mod api { ], ) } - #[doc = " Maximum total number of proposals in storage per multisig (Active + Executed +"] - #[doc = " Cancelled) This prevents unbounded storage growth and incentivizes cleanup"] + #[doc = " Maximum number of proposals in storage per multisig."] + #[doc = " Only Active and Approved proposals are stored; executed and cancelled"] + #[doc = " proposals are removed immediately. This limit prevents unbounded storage growth."] pub fn max_total_proposals_in_storage( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< @@ -19901,7 +19975,8 @@ pub mod api { ], ) } - #[doc = " Fee charged for creating a multisig (non-refundable, burned)"] + #[doc = " Fee charged for creating a multisig (non-refundable, burned)."] + #[doc = " This prevents spam creation of multisig accounts."] pub fn multisig_fee( &self, ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< @@ -19917,23 +19992,6 @@ pub mod api { ], ) } - #[doc = " Deposit reserved for creating a multisig (returned when dissolved)."] - #[doc = " Keeps the state clean by incentivizing removal of unused multisigs."] - pub fn multisig_deposit( - &self, - ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< - ::core::primitive::u128, - > { - ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( - "Multisig", - "MultisigDeposit", - [ - 84u8, 157u8, 140u8, 4u8, 93u8, 57u8, 29u8, 133u8, 105u8, 200u8, 214u8, - 27u8, 144u8, 208u8, 218u8, 160u8, 130u8, 109u8, 101u8, 54u8, 210u8, - 136u8, 71u8, 63u8, 49u8, 237u8, 234u8, 15u8, 178u8, 98u8, 148u8, 156u8, - ], - ) - } #[doc = " Deposit required per proposal (returned on execute or cancel)"] pub fn proposal_deposit( &self, @@ -20023,6 +20081,30 @@ pub mod api { ], ) } + #[doc = " Maximum weight allowed for inner calls executed through the multisig."] + #[doc = ""] + #[doc = " This bound ensures that the `execute` extrinsic can safely reserve weight"] + #[doc = " for the inner call at pre-dispatch time. Proposals with calls exceeding"] + #[doc = " this weight limit are rejected at propose time."] + #[doc = ""] + #[doc = " The execute extrinsic's weight annotation is: bookkeeping + MaxInnerCallWeight."] + #[doc = " This guarantees the block weight is never exceeded by arbitrary inner calls."] + pub fn max_inner_call_weight( + &self, + ) -> ::subxt::ext::subxt_core::constants::address::StaticAddress< + runtime_types::sp_weights::weight_v2::Weight, + > { + ::subxt::ext::subxt_core::constants::address::StaticAddress::new_static( + "Multisig", + "MaxInnerCallWeight", + [ + 149u8, 252u8, 129u8, 80u8, 169u8, 36u8, 79u8, 127u8, 240u8, 156u8, + 56u8, 202u8, 219u8, 86u8, 5u8, 65u8, 245u8, 148u8, 138u8, 243u8, 210u8, + 128u8, 234u8, 216u8, 240u8, 219u8, 123u8, 235u8, 21u8, 158u8, 237u8, + 112u8, + ], + ) + } } } } @@ -20104,12 +20186,15 @@ pub mod api { )] #[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 = "A native token transfer was recorded."] + #[doc = ""] + #[doc = "The `leaf_index` can be used to fetch Merkle proofs via the"] + #[doc = "`zkTrie_getMerkleProof` RPC for ZK circuit verification."] pub struct NativeTransferred { pub from: native_transferred::From, pub to: native_transferred::To, pub amount: native_transferred::Amount, pub transfer_count: native_transferred::TransferCount, - /// Index of this transfer in the ZK trie (for Merkle proof lookup) pub leaf_index: native_transferred::LeafIndex, } pub mod native_transferred { @@ -20131,13 +20216,16 @@ pub mod api { )] #[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 = "A non-native asset transfer was recorded."] + #[doc = ""] + #[doc = "The `leaf_index` can be used to fetch Merkle proofs via the"] + #[doc = "`zkTrie_getMerkleProof` RPC for ZK circuit verification."] 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, - /// Index of this transfer in the ZK trie (for Merkle proof lookup) pub leaf_index: asset_transferred::LeafIndex, } pub mod asset_transferred { @@ -20184,12 +20272,6 @@ pub mod api { pub type UsedNullifiers = ::core::primitive::bool; pub type Param0 = [::core::primitive::u8; 32usize]; } - pub mod transfer_proof { - use super::runtime_types; - pub type TransferProof = [::core::primitive::u8; 32usize]; - pub type Param0 = - (::subxt::ext::subxt_core::utils::AccountId32, ::core::primitive::u64); - } pub mod transfer_count { use super::runtime_types; pub type TransferCount = ::core::primitive::u64; @@ -20249,68 +20331,7 @@ pub mod api { ], ) } - #[doc = " Transfer proofs for wormhole transfers (both native and assets)."] - #[doc = ""] - #[doc = " Storage key: Twox128(\"Wormhole\") || Twox128(\"TransferProof\") || Blake2_256(to,"] - #[doc = " transfer_count) Storage value: leaf_inputs_hash (Poseidon2 hash of full transfer data)"] - #[doc = ""] - #[doc = " The key uses only (to, transfer_count) since transfer_count is atomic per recipient."] - #[doc = " The ZK circuit verifies that the leaf_inputs_hash in the value section matches"] - #[doc = " the Poseidon2 hash of all transfer details (asset_id, count, from, to, amount),"] - #[doc = " providing full 256-bit security."] - 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", - (), - [ - 68u8, 118u8, 236u8, 167u8, 234u8, 90u8, 185u8, 84u8, 179u8, 175u8, - 199u8, 180u8, 115u8, 225u8, 146u8, 36u8, 107u8, 176u8, 147u8, 154u8, - 35u8, 40u8, 9u8, 62u8, 253u8, 6u8, 37u8, 253u8, 83u8, 206u8, 187u8, - 55u8, - ], - ) - } - #[doc = " Transfer proofs for wormhole transfers (both native and assets)."] - #[doc = ""] - #[doc = " Storage key: Twox128(\"Wormhole\") || Twox128(\"TransferProof\") || Blake2_256(to,"] - #[doc = " transfer_count) Storage value: leaf_inputs_hash (Poseidon2 hash of full transfer data)"] - #[doc = ""] - #[doc = " The key uses only (to, transfer_count) since transfer_count is atomic per recipient."] - #[doc = " The ZK circuit verifies that the leaf_inputs_hash in the value section matches"] - #[doc = " the Poseidon2 hash of all transfer details (asset_id, count, from, to, amount),"] - #[doc = " providing full 256-bit security."] - pub fn transfer_proof( - &self, - _0: types::transfer_proof::Param0, - ) -> ::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", - (), - [ - 68u8, 118u8, 236u8, 167u8, 234u8, 90u8, 185u8, 84u8, 179u8, 175u8, - 199u8, 180u8, 115u8, 225u8, 146u8, 36u8, 107u8, 176u8, 147u8, 154u8, - 35u8, 40u8, 9u8, 62u8, 253u8, 6u8, 37u8, 253u8, 83u8, 206u8, 187u8, - 55u8, - ], - ) - } - #[doc = " Transfer count for all wormhole transfers"] + #[doc = " Transfer count per recipient - used to generate unique leaf indices in the ZK trie."] pub fn transfer_count_iter( &self, ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< @@ -20332,7 +20353,7 @@ pub mod api { ], ) } - #[doc = " Transfer count for all wormhole transfers"] + #[doc = " Transfer count per recipient - used to generate unique leaf indices in the ZK trie."] pub fn transfer_count( &self, _0: types::transfer_count::Param0, @@ -20461,6 +20482,252 @@ pub mod api { } } } + pub mod zk_tree { + use super::{root_mod, runtime_types}; + #[doc = "The `Error` enum of this pallet."] + pub type Error = runtime_types::pallet_zk_tree::pallet::Error; + #[doc = "The `Event` enum of this pallet"] + pub type Event = runtime_types::pallet_zk_tree::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")] + #[doc = "A new leaf was inserted into the tree."] + pub struct LeafInserted { + pub index: leaf_inserted::Index, + pub leaf_hash: leaf_inserted::LeafHash, + pub new_root: leaf_inserted::NewRoot, + } + pub mod leaf_inserted { + use super::runtime_types; + pub type Index = ::core::primitive::u64; + pub type LeafHash = [::core::primitive::u8; 32usize]; + pub type NewRoot = [::core::primitive::u8; 32usize]; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for LeafInserted { + const PALLET: &'static str = "ZkTree"; + const EVENT: &'static str = "LeafInserted"; + } + #[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 = "Tree depth increased."] + pub struct TreeGrew { + pub new_depth: tree_grew::NewDepth, + } + pub mod tree_grew { + use super::runtime_types; + pub type NewDepth = ::core::primitive::u8; + } + impl ::subxt::ext::subxt_core::events::StaticEvent for TreeGrew { + const PALLET: &'static str = "ZkTree"; + const EVENT: &'static str = "TreeGrew"; + } + } + pub mod storage { + use super::runtime_types; + pub mod types { + use super::runtime_types; + pub mod leaves { + use super::runtime_types; + pub type Leaves = runtime_types::pallet_zk_tree::ZkLeaf< + ::subxt::ext::subxt_core::utils::AccountId32, + ::core::primitive::u32, + ::core::primitive::u128, + >; + pub type Param0 = ::core::primitive::u64; + } + pub mod nodes { + use super::runtime_types; + pub type Nodes = [::core::primitive::u8; 32usize]; + pub type Param0 = (::core::primitive::u8, ::core::primitive::u64); + } + pub mod leaf_count { + use super::runtime_types; + pub type LeafCount = ::core::primitive::u64; + } + pub mod depth { + use super::runtime_types; + pub type Depth = ::core::primitive::u8; + } + pub mod root { + use super::runtime_types; + pub type Root = [::core::primitive::u8; 32usize]; + } + } + pub struct StorageApi; + impl StorageApi { + #[doc = " Leaf data stored by index."] + pub fn leaves_iter( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::leaves::Leaves, + (), + (), + ::subxt::ext::subxt_core::utils::Yes, + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Leaves", + (), + [ + 179u8, 219u8, 161u8, 103u8, 54u8, 178u8, 204u8, 221u8, 15u8, 0u8, + 103u8, 111u8, 19u8, 89u8, 167u8, 0u8, 200u8, 35u8, 149u8, 127u8, 230u8, + 183u8, 152u8, 151u8, 88u8, 171u8, 223u8, 134u8, 58u8, 122u8, 119u8, + 53u8, + ], + ) + } + #[doc = " Leaf data stored by index."] + pub fn leaves( + &self, + _0: types::leaves::Param0, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + ::subxt::ext::subxt_core::storage::address::StaticStorageKey< + types::leaves::Param0, + >, + types::leaves::Leaves, + ::subxt::ext::subxt_core::utils::Yes, + (), + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Leaves", + ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), + [ + 179u8, 219u8, 161u8, 103u8, 54u8, 178u8, 204u8, 221u8, 15u8, 0u8, + 103u8, 111u8, 19u8, 89u8, 167u8, 0u8, 200u8, 35u8, 149u8, 127u8, 230u8, + 183u8, 152u8, 151u8, 88u8, 171u8, 223u8, 134u8, 58u8, 122u8, 119u8, + 53u8, + ], + ) + } + #[doc = " Internal tree nodes: (level, index) -> hash."] + #[doc = " Level 0 is unused (leaves are hashed on-demand)."] + #[doc = " Level 1+ contains internal node hashes."] + pub fn nodes_iter( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::nodes::Nodes, + (), + (), + ::subxt::ext::subxt_core::utils::Yes, + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Nodes", + (), + [ + 109u8, 135u8, 134u8, 82u8, 149u8, 113u8, 22u8, 231u8, 196u8, 37u8, + 27u8, 29u8, 86u8, 223u8, 101u8, 97u8, 89u8, 147u8, 86u8, 202u8, 170u8, + 24u8, 164u8, 137u8, 71u8, 46u8, 91u8, 69u8, 35u8, 251u8, 152u8, 144u8, + ], + ) + } + #[doc = " Internal tree nodes: (level, index) -> hash."] + #[doc = " Level 0 is unused (leaves are hashed on-demand)."] + #[doc = " Level 1+ contains internal node hashes."] + pub fn nodes( + &self, + _0: types::nodes::Param0, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + ::subxt::ext::subxt_core::storage::address::StaticStorageKey< + types::nodes::Param0, + >, + types::nodes::Nodes, + ::subxt::ext::subxt_core::utils::Yes, + (), + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Nodes", + ::subxt::ext::subxt_core::storage::address::StaticStorageKey::new(_0), + [ + 109u8, 135u8, 134u8, 82u8, 149u8, 113u8, 22u8, 231u8, 196u8, 37u8, + 27u8, 29u8, 86u8, 223u8, 101u8, 97u8, 89u8, 147u8, 86u8, 202u8, 170u8, + 24u8, 164u8, 137u8, 71u8, 46u8, 91u8, 69u8, 35u8, 251u8, 152u8, 144u8, + ], + ) + } + #[doc = " Number of leaves in the tree."] + pub fn leaf_count( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::leaf_count::LeafCount, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "LeafCount", + (), + [ + 67u8, 168u8, 48u8, 81u8, 223u8, 41u8, 216u8, 165u8, 89u8, 116u8, 103u8, + 23u8, 83u8, 40u8, 238u8, 124u8, 63u8, 8u8, 247u8, 246u8, 11u8, 63u8, + 181u8, 30u8, 51u8, 181u8, 232u8, 236u8, 184u8, 121u8, 66u8, 250u8, + ], + ) + } + #[doc = " Current depth of the tree (0 = empty, 1 = up to 4 leaves, etc.)."] + pub fn depth( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::depth::Depth, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Depth", + (), + [ + 15u8, 235u8, 244u8, 51u8, 6u8, 56u8, 103u8, 34u8, 29u8, 165u8, 154u8, + 31u8, 166u8, 174u8, 83u8, 59u8, 232u8, 175u8, 227u8, 168u8, 185u8, + 29u8, 71u8, 211u8, 162u8, 69u8, 81u8, 108u8, 247u8, 107u8, 215u8, 52u8, + ], + ) + } + #[doc = " Current root hash of the tree."] + pub fn root( + &self, + ) -> ::subxt::ext::subxt_core::storage::address::StaticAddress< + (), + types::root::Root, + ::subxt::ext::subxt_core::utils::Yes, + ::subxt::ext::subxt_core::utils::Yes, + (), + > { + ::subxt::ext::subxt_core::storage::address::StaticAddress::new_static( + "ZkTree", + "Root", + (), + [ + 240u8, 224u8, 214u8, 191u8, 99u8, 19u8, 153u8, 102u8, 246u8, 99u8, + 194u8, 80u8, 179u8, 162u8, 75u8, 8u8, 74u8, 143u8, 162u8, 61u8, 251u8, + 71u8, 235u8, 88u8, 14u8, 197u8, 34u8, 40u8, 136u8, 119u8, 201u8, 35u8, + ], + ) + } + } + } + } pub mod runtime_types { use super::runtime_types; pub mod bounded_collections { @@ -23495,7 +23762,6 @@ pub mod api { #[doc = ""] #[doc = "Economic costs:"] #[doc = "- MultisigFee: burned immediately (spam prevention)"] - #[doc = "- MultisigDeposit: reserved until dissolution, then returned to creator (storage bond)"] create_multisig { signers: ::subxt::ext::subxt_core::alloc::vec::Vec< ::subxt::ext::subxt_core::utils::AccountId32, @@ -23522,7 +23788,9 @@ pub mod api { #[doc = "Refunded to actual cost on success based on whether HS path was taken."] propose { multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, - call: ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + call: runtime_types::bounded_collections::bounded_vec::BoundedVec< + ::core::primitive::u8, + >, expiry: ::core::primitive::u32, }, #[codec(index = 2)] @@ -23580,7 +23848,7 @@ pub mod api { claim_deposits { multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, }, - #[codec(index = 7)] + #[codec(index = 6)] #[doc = "Execute an approved proposal"] #[doc = ""] #[doc = "Can be called by any signer of the multisig once the proposal has reached"] @@ -23594,27 +23862,14 @@ pub mod api { #[doc = "Parameters:"] #[doc = "- `multisig_address`: The multisig account"] #[doc = "- `proposal_id`: ID (nonce) of the proposal to execute"] + #[doc = ""] + #[doc = "Note: The weight charged includes both multisig bookkeeping and MaxInnerCallWeight."] + #[doc = "Actual weight is refunded based on the inner call's post-dispatch info."] + #[doc = "The inner call's weight is validated against MaxInnerCallWeight at propose time."] execute { multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, proposal_id: ::core::primitive::u32, }, - #[codec(index = 6)] - #[doc = "Approve dissolving a multisig account"] - #[doc = ""] - #[doc = "Signers call this to approve dissolving the multisig."] - #[doc = "When threshold is reached, the multisig is automatically dissolved."] - #[doc = ""] - #[doc = "Requirements:"] - #[doc = "- Caller must be a signer"] - #[doc = "- No proposals exist (active, executed, or cancelled) - must be fully cleaned up"] - #[doc = "- Multisig account balance must be zero"] - #[doc = ""] - #[doc = "When threshold is reached:"] - #[doc = "- Deposit is returned to creator"] - #[doc = "- Multisig storage is removed"] - approve_dissolve { - multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, - }, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -23631,6 +23886,7 @@ pub mod api { pub enum Error { #[codec(index = 0)] #[doc = "Not enough signers provided"] + #[doc = "Multisig requires at least 2 unique signers"] NotEnoughSigners, #[codec(index = 1)] #[doc = "Threshold must be greater than zero"] @@ -23642,74 +23898,68 @@ pub mod api { #[doc = "Too many signers"] TooManySigners, #[codec(index = 4)] - #[doc = "Duplicate signer in list"] - DuplicateSigner, - #[codec(index = 5)] #[doc = "Multisig already exists"] MultisigAlreadyExists, - #[codec(index = 6)] + #[codec(index = 5)] #[doc = "Multisig not found"] MultisigNotFound, - #[codec(index = 7)] + #[codec(index = 6)] #[doc = "Caller is not a signer of this multisig"] NotASigner, - #[codec(index = 8)] + #[codec(index = 7)] #[doc = "Proposal not found"] ProposalNotFound, - #[codec(index = 9)] + #[codec(index = 8)] #[doc = "Caller is not the proposer"] NotProposer, - #[codec(index = 10)] + #[codec(index = 9)] #[doc = "Already approved by this signer"] AlreadyApproved, - #[codec(index = 11)] + #[codec(index = 10)] #[doc = "Not enough approvals to execute"] NotEnoughApprovals, - #[codec(index = 12)] + #[codec(index = 11)] #[doc = "Proposal expiry is in the past"] ExpiryInPast, - #[codec(index = 13)] + #[codec(index = 12)] #[doc = "Proposal expiry is too far in the future (exceeds MaxExpiryDuration)"] ExpiryTooFar, - #[codec(index = 14)] + #[codec(index = 13)] #[doc = "Proposal has expired"] ProposalExpired, - #[codec(index = 15)] - #[doc = "Call data too large"] - CallTooLarge, - #[codec(index = 16)] + #[codec(index = 14)] #[doc = "Failed to decode call data"] InvalidCall, - #[codec(index = 17)] + #[codec(index = 15)] #[doc = "Too many total proposals in storage for this multisig (cleanup required)"] TooManyProposalsInStorage, - #[codec(index = 18)] + #[codec(index = 16)] #[doc = "This signer has too many proposals in storage (filibuster protection)"] TooManyProposalsPerSigner, - #[codec(index = 19)] + #[codec(index = 17)] #[doc = "Insufficient balance for deposit"] InsufficientBalance, - #[codec(index = 20)] + #[codec(index = 18)] #[doc = "Proposal has active deposit"] ProposalHasDeposit, - #[codec(index = 21)] + #[codec(index = 19)] #[doc = "Proposal has not expired yet"] ProposalNotExpired, - #[codec(index = 22)] - #[doc = "Proposal is not active (already executed or cancelled)"] + #[codec(index = 20)] + #[doc = "Proposal is not in a cancellable state (must be Active or Approved)"] ProposalNotActive, - #[codec(index = 23)] + #[codec(index = 21)] #[doc = "Proposal has not been approved yet (threshold not reached)"] ProposalNotApproved, - #[codec(index = 24)] - #[doc = "Cannot dissolve multisig with existing proposals (clear them first)"] - ProposalsExist, - #[codec(index = 25)] - #[doc = "Multisig account must have zero balance before dissolution"] - MultisigAccountNotZero, - #[codec(index = 26)] + #[codec(index = 22)] #[doc = "Call is not allowed for high-security multisig"] CallNotAllowedForHighSecurityMultisig, + #[codec(index = 23)] + #[doc = "Proposal nonce exhausted (u32::MAX reached)"] + ProposalNonceExhausted, + #[codec(index = 24)] + #[doc = "Call weight exceeds MaxInnerCallWeight limit"] + CallWeightExceedsLimit, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -23744,8 +23994,8 @@ pub mod api { proposal_id: ::core::primitive::u32, }, #[codec(index = 2)] - #[doc = "A proposal has been approved by a signer"] - ProposalApproved { + #[doc = "A signer has approved a proposal (does not imply threshold reached)"] + SignerApproved { multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, approver: ::subxt::ext::subxt_core::utils::AccountId32, proposal_id: ::core::primitive::u32, @@ -23794,23 +24044,6 @@ pub mod api { claimer: ::subxt::ext::subxt_core::utils::AccountId32, total_returned: ::core::primitive::u128, proposals_removed: ::core::primitive::u32, - multisig_removed: ::core::primitive::bool, - }, - #[codec(index = 8)] - #[doc = "A signer approved dissolving the multisig"] - DissolveApproved { - multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, - approver: ::subxt::ext::subxt_core::utils::AccountId32, - approvals_count: ::core::primitive::u32, - }, - #[codec(index = 9)] - #[doc = "A multisig account was dissolved (threshold reached)"] - MultisigDissolved { - multisig_address: ::subxt::ext::subxt_core::utils::AccountId32, - deposit_returned: ::subxt::ext::subxt_core::utils::AccountId32, - approvers: ::subxt::ext::subxt_core::alloc::vec::Vec< - ::subxt::ext::subxt_core::utils::AccountId32, - >, }, } } @@ -23821,14 +24054,12 @@ pub mod api { )] #[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 MultisigData<_0, _1, _2, _3> { + pub struct MultisigData<_0, _1, _2> { pub creator: _0, pub signers: _1, pub threshold: ::core::primitive::u32, pub proposal_nonce: ::core::primitive::u32, - pub deposit: _2, - pub active_proposals: ::core::primitive::u32, - pub proposals_per_signer: _3, + pub proposals_per_signer: _2, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -23840,6 +24071,7 @@ pub mod api { pub struct ProposalData<_0, _1, _2, _3, _4> { pub proposer: _0, pub call: _3, + pub call_weight: runtime_types::sp_weights::weight_v2::Weight, pub expiry: _2, pub approvals: _4, pub deposit: _1, @@ -23857,10 +24089,6 @@ pub mod api { Active, #[codec(index = 1)] Approved, - #[codec(index = 2)] - Executed, - #[codec(index = 3)] - Cancelled, } } pub mod pallet_preimage { @@ -25284,22 +25512,41 @@ pub mod api { #[doc = "Enable high-security for the calling account with a specified"] #[doc = "reversibility delay."] #[doc = ""] - #[doc = "Recoverer and interceptor (aka guardian) could be the same account or"] - #[doc = "different accounts."] - #[doc = ""] #[doc = "Once an account is set as high security it can only make reversible"] #[doc = "transfers. It is not allowed any other calls."] #[doc = ""] - #[doc = "- `delay`: The reversibility time for any transfer made by the high"] - #[doc = "security account."] - #[doc = "- interceptor: The account that can intercept transctions from the"] - #[doc = "high security account."] + #[doc = "# Warning: Permanent and Irreversible"] + #[doc = ""] + #[doc = "**Enabling high security mode is a one-way operation that cannot be undone.**"] + #[doc = ""] + #[doc = "Once this function is called successfully, the account is permanently restricted"] + #[doc = "to only the following operations:"] + #[doc = "- [`schedule_transfer`](Self::schedule_transfer) - Schedule delayed native token"] + #[doc = " transfers"] + #[doc = "- [`schedule_asset_transfer`](Self::schedule_asset_transfer) - Schedule delayed asset"] + #[doc = " transfers"] + #[doc = "- [`cancel`](Self::cancel) - Cancel pending transfers"] + #[doc = "- [`recover_funds`](Self::recover_funds) - Guardian-initiated emergency fund recovery"] + #[doc = ""] + #[doc = "There is no mechanism to disable high security mode or restore normal account"] + #[doc = "functionality. This design is intentional to provide maximum security guarantees:"] + #[doc = "an attacker who gains access to the account cannot simply disable the protections."] + #[doc = ""] + #[doc = "Users who no longer wish to use high-security features can simply transfer their"] + #[doc = "funds to a different account using [`schedule_transfer`](Self::schedule_transfer)"] + #[doc = "or [`schedule_asset_transfer`](Self::schedule_asset_transfer)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `delay`: The reversibility time for any transfer made by the high-security account."] + #[doc = "- `guardian`: The guardian account that can cancel pending transfers and recover funds"] + #[doc = " from this high-security account."] set_high_security { delay: runtime_types::qp_scheduler::BlockNumberOrTimestamp< ::core::primitive::u32, ::core::primitive::u64, >, - interceptor: ::subxt::ext::subxt_core::utils::AccountId32, + guardian: ::subxt::ext::subxt_core::utils::AccountId32, }, #[codec(index = 1)] #[doc = "Cancel a pending reversible transaction scheduled by the caller."] @@ -25307,9 +25554,22 @@ pub mod api { #[doc = "- `tx_id`: The unique identifier of the transaction to cancel."] cancel { tx_id: ::subxt::ext::subxt_core::utils::H256 }, #[codec(index = 2)] - #[doc = "Called by the Scheduler to finalize the scheduled task/call"] + #[doc = "Executes a previously scheduled transfer after the delay period has elapsed."] + #[doc = ""] + #[doc = "This extrinsic is called automatically by the Scheduler pallet when the"] + #[doc = "delay period expires. It must be signed by this pallet's account (not a user)."] + #[doc = "The pallet account is set as the origin when scheduling via"] + #[doc = "[`do_schedule_transfer_inner`](Self::do_schedule_transfer_inner)."] + #[doc = ""] + #[doc = "# Parameters"] + #[doc = ""] + #[doc = "- `tx_id`: The unique identifier of the pending transfer to execute."] #[doc = ""] - #[doc = "- `tx_id`: The unique id of the transaction to finalize and dispatch."] + #[doc = "# Errors"] + #[doc = ""] + #[doc = "- [`InvalidSchedulerOrigin`](Error::InvalidSchedulerOrigin): Called by an account other"] + #[doc = " than this pallet's account."] + #[doc = "- [`PendingTxNotFound`](Error::PendingTxNotFound): No pending transfer with this ID."] execute_transfer { tx_id: ::subxt::ext::subxt_core::utils::H256 }, #[codec(index = 3)] #[doc = "Schedule a transaction for delayed execution."] @@ -25364,12 +25624,16 @@ pub mod api { >, }, #[codec(index = 7)] - #[doc = "Allows the guardian (interceptor) to recover all funds from a high security"] - #[doc = "account by transferring the entire balance to themselves."] + #[doc = "Allows the guardian to recover all funds from a high-security account"] + #[doc = "by transferring the entire balance to themselves."] #[doc = ""] - #[doc = "This is an emergency function for when the high security account may be compromised."] + #[doc = "This is an emergency function for when the high-security account may be compromised."] #[doc = "It cancels all pending transfers first (applying volume fees), then transfers"] #[doc = "the remaining free balance to the guardian."] + #[doc = ""] + #[doc = "If releasing held funds fails for any transfer, that transfer is skipped (metadata"] + #[doc = "preserved for manual retry via `cancel`) and a `TransferRecoveryFailed` event is"] + #[doc = "emitted. Other transfers continue to be processed."] recover_funds { account: ::subxt::ext::subxt_core::utils::AccountId32 }, } #[derive( @@ -25392,8 +25656,8 @@ pub mod api { #[doc = "The account attempting the action is not marked as high security."] AccountNotHighSecurity, #[codec(index = 2)] - #[doc = "Interceptor can not be the account itself, because it is redundant."] - InterceptorCannotBeSelf, + #[doc = "Guardian cannot be the account itself, because it is redundant."] + GuardianCannotBeSelf, #[codec(index = 3)] #[doc = "Recoverer cannot be the account itself, because it is redundant."] RecovererCannotBeSelf, @@ -25432,8 +25696,8 @@ pub mod api { #[doc = "deterrence)"] AccountAlreadyReversibleCannotScheduleOneTime, #[codec(index = 15)] - #[doc = "The interceptor has reached the maximum number of accounts they can intercept for."] - TooManyInterceptorAccounts, + #[doc = "The guardian has reached the maximum number of accounts they can protect."] + TooManyGuardianAccounts, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -25450,22 +25714,20 @@ pub mod api { pub enum Event { #[codec(index = 0)] #[doc = "A user has enabled their high-security settings."] - #[doc = "[who, interceptor, recoverer, delay]"] HighSecuritySet { who: ::subxt::ext::subxt_core::utils::AccountId32, - interceptor: ::subxt::ext::subxt_core::utils::AccountId32, + guardian: ::subxt::ext::subxt_core::utils::AccountId32, delay: runtime_types::qp_scheduler::BlockNumberOrTimestamp< ::core::primitive::u32, ::core::primitive::u64, >, }, #[codec(index = 1)] - #[doc = "A transaction has been intercepted and scheduled for delayed execution."] - #[doc = "[from, to, interceptor, amount, tx_id, execute_at_moment]"] + #[doc = "A transaction has been scheduled for delayed execution."] TransactionScheduled { from: ::subxt::ext::subxt_core::utils::AccountId32, to: ::subxt::ext::subxt_core::utils::AccountId32, - interceptor: ::subxt::ext::subxt_core::utils::AccountId32, + guardian: ::subxt::ext::subxt_core::utils::AccountId32, asset_id: ::core::option::Option<::core::primitive::u32>, amount: ::core::primitive::u128, tx_id: ::subxt::ext::subxt_core::utils::H256, @@ -25475,7 +25737,7 @@ pub mod api { >, }, #[codec(index = 2)] - #[doc = "A scheduled transaction has been successfully cancelled by the owner."] + #[doc = "A scheduled transaction has been successfully cancelled."] TransactionCancelled { who: ::subxt::ext::subxt_core::utils::AccountId32, tx_id: ::subxt::ext::subxt_core::utils::H256, @@ -25492,11 +25754,15 @@ pub mod api { >, }, #[codec(index = 4)] - #[doc = "Funds were recovered from a high security account by its guardian."] + #[doc = "All funds were recovered from a high-security account by its guardian."] FundsRecovered { account: ::subxt::ext::subxt_core::utils::AccountId32, guardian: ::subxt::ext::subxt_core::utils::AccountId32, }, + #[codec(index = 5)] + #[doc = "Failed to release held funds during recovery. The transfer metadata is preserved"] + #[doc = "for manual retry via `cancel`."] + TransferRecoveryFailed { tx_id: ::subxt::ext::subxt_core::utils::H256 }, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -25522,7 +25788,7 @@ pub mod api { #[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 HighSecurityAccountData<_0, _1> { - pub interceptor: _0, + pub guardian: _0, pub delay: _1, } #[derive( @@ -25535,8 +25801,8 @@ pub mod api { pub struct PendingTransfer<_0, _1, _2> { pub from: _0, pub to: _0, - pub interceptor: _0, - pub call: _2, + pub guardian: _0, + pub asset_id: ::core::option::Option<_2>, pub amount: _1, } } @@ -25621,6 +25887,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] set_retry { task: ( runtime_types::qp_scheduler::BlockNumberOrTimestamp< @@ -25647,6 +25917,10 @@ pub mod api { #[doc = "clones of the original task. Their retry configuration will be derived from the"] #[doc = "original task's configuration, but will have a lower value for `remaining` than the"] #[doc = "original `total_retries`."] + #[doc = ""] + #[doc = "The `period` type must match the task's scheduling type: block-scheduled tasks"] + #[doc = "require a block-number period, and timestamp-scheduled tasks require a timestamp"] + #[doc = "period. Mismatched types will return [`Error::RetryPeriodMismatch`]."] set_retry_named { id: [::core::primitive::u8; 32usize], retries: ::core::primitive::u8, @@ -25701,6 +25975,15 @@ pub mod api { #[codec(index = 5)] #[doc = "Attempt to use a non-named function on a named task."] Named, + #[codec(index = 6)] + #[doc = "Periodic scheduling is not supported."] + PeriodicNotSupported, + #[codec(index = 7)] + #[doc = "Retry period type does not match task scheduling type."] + #[doc = ""] + #[doc = "Block-scheduled tasks require a block-number retry period,"] + #[doc = "and timestamp-scheduled tasks require a timestamp retry period."] + RetryPeriodMismatch, } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -26007,6 +26290,11 @@ pub mod api { pub enum Call { #[codec(index = 0)] #[doc = "Set the treasury account. Root only. Zero address is rejected (funds would be locked)."] + #[doc = ""] + #[doc = "**Important**: This only changes where *future* mining rewards are sent. Any balance"] + #[doc = "that has already accumulated in the current treasury account is NOT automatically"] + #[doc = "migrated to the new account. If you need to move existing funds, perform a separate"] + #[doc = "balance transfer (e.g., via governance proposal) after updating the account."] set_treasury_account { account: ::subxt::ext::subxt_core::utils::AccountId32 }, #[codec(index = 1)] #[doc = "Set the treasury portion (Permill, 0–100%). Root only."] @@ -26047,10 +26335,18 @@ pub mod api { #[doc = "The `Event` enum of this pallet"] pub enum Event { #[codec(index = 0)] + #[doc = "The treasury account was updated."] + #[doc = ""] + #[doc = "Note: This only redirects where future mining rewards are sent. Any balance"] + #[doc = "accumulated in the old account remains there and is NOT automatically migrated."] + #[doc = "Use a separate balance transfer if funds need to be moved."] TreasuryAccountUpdated { + old_account: + ::core::option::Option<::subxt::ext::subxt_core::utils::AccountId32>, new_account: ::subxt::ext::subxt_core::utils::AccountId32, }, #[codec(index = 1)] + #[doc = "The treasury portion (share of mining rewards) was updated."] TreasuryPortionUpdated { new_portion: runtime_types::sp_arithmetic::per_things::Permill, }, @@ -26374,19 +26670,29 @@ pub mod api { #[doc = "The `Event` enum of this pallet"] pub enum Event { #[codec(index = 0)] + #[doc = "A native token transfer was recorded."] + #[doc = ""] + #[doc = "The `leaf_index` can be used to fetch Merkle proofs via the"] + #[doc = "`zkTrie_getMerkleProof` RPC for ZK circuit verification."] NativeTransferred { from: ::subxt::ext::subxt_core::utils::AccountId32, to: ::subxt::ext::subxt_core::utils::AccountId32, amount: ::core::primitive::u128, transfer_count: ::core::primitive::u64, + leaf_index: ::core::primitive::u64, }, #[codec(index = 1)] + #[doc = "A non-native asset transfer was recorded."] + #[doc = ""] + #[doc = "The `leaf_index` can be used to fetch Merkle proofs via the"] + #[doc = "`zkTrie_getMerkleProof` RPC for ZK circuit verification."] 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, + leaf_index: ::core::primitive::u64, }, #[codec(index = 2)] ProofVerified { @@ -26398,6 +26704,86 @@ pub mod api { } } } + pub mod pallet_zk_tree { + 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 = "The `Error` enum of this pallet."] + pub enum Error { + #[codec(index = 0)] + #[doc = "Leaf index out of bounds."] + LeafIndexOutOfBounds, + #[codec(index = 1)] + #[doc = "Leaf not found."] + LeafNotFound, + } + #[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)] + #[doc = "A new leaf was inserted into the tree."] + LeafInserted { + index: ::core::primitive::u64, + leaf_hash: [::core::primitive::u8; 32usize], + new_root: [::core::primitive::u8; 32usize], + }, + #[codec(index = 1)] + #[doc = "Tree depth increased."] + TreeGrew { new_depth: ::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")] + pub struct ZkLeaf<_0, _1, _2> { + pub to: _0, + pub transfer_count: ::core::primitive::u64, + pub asset_id: _1, + pub amount: _2, + } + #[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 ZkMerkleProofRpc { + pub leaf_index: ::core::primitive::u64, + pub leaf_data: ::subxt::ext::subxt_core::alloc::vec::Vec<::core::primitive::u8>, + pub leaf_hash: [::core::primitive::u8; 32usize], + pub siblings: ::subxt::ext::subxt_core::alloc::vec::Vec< + [[::core::primitive::u8; 32usize]; 3usize], + >, + pub root: [::core::primitive::u8; 32usize], + pub depth: ::core::primitive::u8, + } + } pub mod primitive_types { use super::runtime_types; #[derive( @@ -26460,6 +26846,7 @@ pub mod api { pub number: _0, pub state_root: ::subxt::ext::subxt_core::utils::H256, pub extrinsics_root: ::subxt::ext::subxt_core::utils::H256, + pub zk_tree_root: ::subxt::ext::subxt_core::utils::H256, pub digest: runtime_types::sp_runtime::generic::digest::Digest, } } @@ -26645,6 +27032,8 @@ pub mod api { Multisig(runtime_types::pallet_multisig::pallet::Error), #[codec(index = 20)] Wormhole(runtime_types::pallet_wormhole::pallet::Error), + #[codec(index = 21)] + ZkTree(runtime_types::pallet_zk_tree::pallet::Error), } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, @@ -26692,6 +27081,8 @@ pub mod api { Multisig(runtime_types::pallet_multisig::pallet::Event), #[codec(index = 20)] Wormhole(runtime_types::pallet_wormhole::pallet::Event), + #[codec(index = 21)] + ZkTree(runtime_types::pallet_zk_tree::pallet::Event), } #[derive( :: subxt :: ext :: subxt_core :: ext :: scale_decode :: DecodeAsType, diff --git a/src/cli/high_security.rs b/src/cli/high_security.rs index d03f726..dadded4 100644 --- a/src/cli/high_security.rs +++ b/src/cli/high_security.rs @@ -96,10 +96,10 @@ pub async fn handle_high_security_command( if let Some(high_security_data) = value { log_success!("✅ High Security: ENABLED"); - // Convert interceptor to Quantus SS58 format - let interceptor_ss58 = high_security_data.interceptor.to_quantus_ss58(); + // Convert guardian to Quantus SS58 format + let guardian_ss58 = high_security_data.guardian.to_quantus_ss58(); - log_print!("🛡️ Guardian/Interceptor: {}", interceptor_ss58.bright_green()); + log_print!("🛡️ Guardian: {}", guardian_ss58.bright_green()); // Format delay display match high_security_data.delay { @@ -200,7 +200,7 @@ pub async fn handle_high_security_command( // Query storage for entrusted accounts let storage_addr = quantus_subxt::api::storage() .reversible_transfers() - .interceptor_index(guardian_account); + .guardian_index(guardian_account); let latest = quantus_client.get_latest_block().await?; let value = quantus_client .client() diff --git a/src/cli/multisig.rs b/src/cli/multisig.rs index 057d20b..3a7e96e 100644 --- a/src/cli/multisig.rs +++ b/src/cli/multisig.rs @@ -32,10 +32,6 @@ pub struct MultisigInfo { pub signers: Vec, /// Next proposal ID pub proposal_nonce: u32, - /// Locked deposit amount (returned to creator on dissolve) - pub deposit: u128, - /// Number of active proposals - pub active_proposals: u32, } /// Proposal status @@ -45,8 +41,6 @@ pub enum ProposalStatus { Active, /// Threshold reached; any signer can call execute to dispatch Approved, - Executed, - Cancelled, } /// Proposal information @@ -588,7 +582,7 @@ pub async fn propose_transfer( // Build propose transaction let propose_tx = - quantus_subxt::api::tx().multisig().propose(multisig_address, call_data, expiry); + quantus_subxt::api::tx().multisig().propose(multisig_address, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); // Submit transaction let execution_mode = ExecutionMode { finalized: false, wait_for_transaction: false }; @@ -618,7 +612,7 @@ pub async fn propose_custom( ) -> crate::error::Result { // Build propose transaction let propose_tx = - quantus_subxt::api::tx().multisig().propose(multisig_address, call_data, expiry); + quantus_subxt::api::tx().multisig().propose(multisig_address, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); // Submit transaction let execution_mode = ExecutionMode { finalized: false, wait_for_transaction: false }; @@ -740,8 +734,6 @@ pub async fn get_multisig_info( threshold: data.threshold, signers, proposal_nonce: data.proposal_nonce, - deposit: data.deposit, - active_proposals: data.active_proposals, })) } else { Ok(None) @@ -790,10 +782,6 @@ pub async fn get_proposal_info( ProposalStatus::Active, quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Approved => ProposalStatus::Approved, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Executed => - ProposalStatus::Executed, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Cancelled => - ProposalStatus::Cancelled, }; Ok(Some(ProposalInfo { @@ -864,10 +852,6 @@ pub async fn list_proposals( ProposalStatus::Active, quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Approved => ProposalStatus::Approved, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Executed => - ProposalStatus::Executed, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Cancelled => - ProposalStatus::Cancelled, }; proposals.push(ProposalInfo { @@ -892,31 +876,6 @@ pub async fn list_proposals( /// Requirements: /// - No proposals exist (active, executed, or cancelled) /// - Multisig account balance must be zero -/// - Deposit is returned to creator -/// -/// # Returns -/// Transaction hash -#[allow(dead_code)] -pub async fn approve_dissolve_multisig( - quantus_client: &crate::chain::client::QuantusClient, - caller_keypair: &crate::wallet::QuantumKeyPair, - multisig_address: subxt::ext::subxt_core::utils::AccountId32, -) -> crate::error::Result { - let approve_tx = quantus_subxt::api::tx().multisig().approve_dissolve(multisig_address); - - let execution_mode = ExecutionMode { finalized: false, wait_for_transaction: false }; - let tx_hash = crate::cli::common::submit_transaction( - quantus_client, - caller_keypair, - approve_tx, - None, - execution_mode, - ) - .await?; - - Ok(tx_hash) -} - // ============================================================================ // CLI HANDLERS (Internal) // ============================================================================ @@ -1588,7 +1547,7 @@ async fn handle_propose( let propose_tx = quantus_subxt::api::tx() .multisig() - .propose(multisig_address.clone(), call_data, expiry); + .propose(multisig_address.clone(), quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; @@ -1656,7 +1615,7 @@ async fn handle_propose_with_call_data( let propose_tx = quantus_subxt::api::tx() .multisig() - .propose(multisig_account_id, call_data, expiry); + .propose(multisig_account_id, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; @@ -2048,73 +2007,18 @@ async fn handle_claim_deposits( /// Approve dissolving a multisig async fn handle_dissolve( - multisig_address: String, - from: String, - password: Option, - password_file: Option, - node_url: &str, - execution_mode: ExecutionMode, + _multisig_address: String, + _from: String, + _password: Option, + _password_file: Option, + _node_url: &str, + _execution_mode: ExecutionMode, ) -> crate::error::Result<()> { - log_print!("🗑️ {} Approving multisig dissolution...", "MULTISIG".bright_magenta().bold()); - - // Resolve multisig address - let multisig_ss58 = crate::cli::common::resolve_address(&multisig_address)?; - let (multisig_id, _) = - SpAccountId32::from_ss58check_with_version(&multisig_ss58).map_err(|e| { - crate::error::QuantusError::Generic(format!("Invalid multisig address: {:?}", e)) - })?; - let multisig_bytes: [u8; 32] = *multisig_id.as_ref(); - let multisig_address_id = subxt::ext::subxt_core::utils::AccountId32::from(multisig_bytes); - - // Load keypair - let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; - - // Connect to chain - let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; - - // Get threshold for info message - let latest_block_hash = quantus_client.get_latest_block().await?; - let storage_at = quantus_client.client().storage().at(latest_block_hash); - let multisig_query = - quantus_subxt::api::storage().multisig().multisigs(multisig_address_id.clone()); - let multisig_info = storage_at.fetch(&multisig_query).await?; - - // Build transaction - let approve_tx = quantus_subxt::api::tx() - .multisig() - .approve_dissolve(multisig_address_id.clone()); - - // Always wait for transaction confirmation - runtime validates all conditions - let dissolve_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; - - // Submit transaction and wait for on-chain confirmation - crate::cli::common::submit_transaction( - &quantus_client, - &keypair, - approve_tx, - None, - dissolve_execution_mode, - ) - .await?; - - log_success!("✅ Dissolution approval confirmed on-chain"); - - if let Some(info) = multisig_info { - // Convert creator to SS58 - let creator_bytes: &[u8; 32] = info.creator.as_ref(); - let creator_sp = SpAccountId32::from(*creator_bytes); - let creator_ss58 = creator_sp.to_ss58check(); - - log_print!(" Requires {} total approvals to dissolve", info.threshold); - log_print!(""); - log_print!("💡 {} When threshold is reached:", "INFO".bright_blue().bold()); - log_print!(" - Multisig will be dissolved automatically"); - log_print!(" - Deposit ({}) will be RETURNED to creator", format_balance(info.deposit)); - log_print!(" - Creator: {}", creator_ss58.bright_cyan()); - log_print!(" - Storage will be removed"); - } - - Ok(()) + Err(crate::error::QuantusError::Generic( + "Multisig dissolution has been removed from the chain. \ + To recover funds from a multisig, use the standard proposal workflow to transfer funds out." + .to_string(), + )) } /// Query multisig information (or specific proposal if proposal_id provided) @@ -2204,119 +2108,62 @@ async fn handle_info( log_print!(" {}. {}", i + 1, signer_sp.to_ss58check().bright_cyan()); } log_print!(" Proposal Nonce: {}", data.proposal_nonce); - log_print!( - " Deposit: {} (returned to creator on dissolve)", - format_balance(data.deposit) - ); - log_print!( - " Active Proposals: {}", - data.active_proposals.to_string().bright_yellow() - ); - // Show active proposals summary if any exist - if data.active_proposals > 0 { - log_print!(""); - log_print!("📝 {} Active Proposals:", "PROPOSALS".bright_magenta().bold()); - let proposals_query = quantus_subxt::api::storage() - .multisig() - .proposals_iter1(multisig_address.clone()); - let mut proposals_stream = storage_at.iter(proposals_query).await?; - while let Some(Ok(kv)) = proposals_stream.next().await { - let proposal = kv.value; - // Extract proposal ID from key_bytes (last 4 bytes = u32 LE) - let proposal_id = if kv.key_bytes.len() >= 4 { - let id_bytes = &kv.key_bytes[kv.key_bytes.len() - 4..]; - u32::from_le_bytes([id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3]]) - } else { - 0 - }; - let status = match proposal.status { - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Active => - "Active".bright_green(), - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Approved => - "Approved (ready to execute)".bright_yellow(), - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Executed => - "Executed".bright_blue(), - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Cancelled => - "Cancelled".bright_red(), - }; - // Decode call name from the call field - let call_name = if proposal.call.0.len() >= 2 { - let pallet_idx = proposal.call.0[0]; - let call_idx = proposal.call.0[1]; - let metadata = quantus_client.client().metadata(); - if let Some(pallet) = metadata.pallet_by_index(pallet_idx) { - if let Some(variant) = pallet.call_variant_by_index(call_idx) { - format!("{}::{}", pallet.name(), variant.name) - } else { - format!("{}::call[{}]", pallet.name(), call_idx) - } + // Show active proposals summary + log_print!(""); + log_print!("📝 {} Active Proposals:", "PROPOSALS".bright_magenta().bold()); + let proposals_query = quantus_subxt::api::storage() + .multisig() + .proposals_iter1(multisig_address.clone()); + let mut proposals_stream = storage_at.iter(proposals_query).await?; + let mut proposal_count = 0; + while let Some(Ok(kv)) = proposals_stream.next().await { + proposal_count += 1; + let proposal = kv.value; + // Extract proposal ID from key_bytes (last 4 bytes = u32 LE) + let proposal_id = if kv.key_bytes.len() >= 4 { + let id_bytes = &kv.key_bytes[kv.key_bytes.len() - 4..]; + u32::from_le_bytes([id_bytes[0], id_bytes[1], id_bytes[2], id_bytes[3]]) + } else { + 0 + }; + let status = match proposal.status { + quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Active => + "Active".bright_green(), + quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Approved => + "Approved (ready to execute)".bright_yellow(), + }; + // Decode call name from the call field + let call_name = if proposal.call.0.len() >= 2 { + let pallet_idx = proposal.call.0[0]; + let call_idx = proposal.call.0[1]; + let metadata = quantus_client.client().metadata(); + if let Some(pallet) = metadata.pallet_by_index(pallet_idx) { + if let Some(variant) = pallet.call_variant_by_index(call_idx) { + format!("{}::{}", pallet.name(), variant.name) } else { - format!("pallet[{}]::call[{}]", pallet_idx, call_idx) + format!("{}::call[{}]", pallet.name(), call_idx) } } else { - format!("({}B encoded)", proposal.call.0.len()) - }; - let proposer_bytes: &[u8; 32] = proposal.proposer.as_ref(); - let proposer_sp = SpAccountId32::from(*proposer_bytes); - log_print!( - " #{}: {} | {} | Approvals: {} | Proposer: {}", - proposal_id, - call_name.bright_white(), - status, - proposal.approvals.0.len(), - proposer_sp.to_ss58check().dimmed() - ); - } - } - - // Check for dissolution progress - let dissolve_query = quantus_subxt::api::storage() - .multisig() - .dissolve_approvals(multisig_address.clone()); - if let Some(dissolve_approvals) = storage_at.fetch(&dissolve_query).await? { - log_print!(""); - log_print!("🗑️ {} Dissolution in progress:", "DISSOLVE".bright_red().bold()); - log_print!( - " Progress: {}/{}", - dissolve_approvals.0.len().to_string().bright_yellow(), - data.threshold.to_string().bright_yellow() - ); - log_print!(" Approvals:"); - for (i, approver) in dissolve_approvals.0.iter().enumerate() { - let approver_bytes: &[u8; 32] = approver.as_ref(); - let approver_sp = SpAccountId32::from(*approver_bytes); - log_print!(" {}. {}", i + 1, approver_sp.to_ss58check().bright_cyan()); - } - - // Show pending approvals - let pending_signers: Vec<_> = - data.signers.0.iter().filter(|s| !dissolve_approvals.0.contains(s)).collect(); - - if !pending_signers.is_empty() { - log_print!(" Pending:"); - for (i, signer) in pending_signers.iter().enumerate() { - let signer_bytes: &[u8; 32] = signer.as_ref(); - let signer_sp = SpAccountId32::from(*signer_bytes); - log_print!(" {}. {}", i + 1, signer_sp.to_ss58check().dimmed()); + format!("pallet[{}]::call[{}]", pallet_idx, call_idx) } - } - - log_print!(""); - log_print!(" ⚠️ {} When threshold is reached:", "WARNING".bright_red().bold()); - log_print!(" - Multisig will be dissolved IMMEDIATELY"); - log_print!( - " - Deposit will be RETURNED to creator: {}", - creator_ss58.bright_cyan() - ); - } else { - log_print!(""); + } else { + format!("({}B encoded)", proposal.call.0.len()) + }; + let proposer_bytes: &[u8; 32] = proposal.proposer.as_ref(); + let proposer_sp = SpAccountId32::from(*proposer_bytes); log_print!( - " 💡 {} Deposit ({}) will be returned to creator on dissolve", - "INFO".bright_blue().bold(), - format_balance(data.deposit) + " #{}: {} | {} | Approvals: {} | Proposer: {}", + proposal_id, + call_name.bright_white(), + status, + proposal.approvals.0.len(), + proposer_sp.to_ss58check().dimmed() ); } + if proposal_count == 0 { + log_print!(" No active proposals"); + } }, None => { log_error!("❌ Multisig not found at address: {}", multisig_ss58); @@ -2646,10 +2493,6 @@ async fn handle_proposal_info( "Active".bright_green(), quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Approved => "Approved (ready to execute)".bright_yellow(), - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Executed => - "Executed".bright_blue(), - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Cancelled => - "Cancelled".bright_red(), } ); log_print!(" Approvals ({}):", data.approvals.0.len().to_string().bright_yellow()); @@ -2730,8 +2573,6 @@ async fn handle_list_proposals( let mut count = 0; let mut active_count = 0; let mut approved_count = 0; - let mut executed_count = 0; - let mut cancelled_count = 0; while let Some(result) = proposals.next().await { match result { @@ -2747,14 +2588,6 @@ async fn handle_list_proposals( approved_count += 1; "Approved (ready to execute)".bright_yellow() }, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Executed => { - executed_count += 1; - "Executed".bright_blue() - }, - quantus_subxt::api::runtime_types::pallet_multisig::ProposalStatus::Cancelled => { - cancelled_count += 1; - "Cancelled".bright_red() - }, }; // Extract proposal ID from key_bytes (u32, 4 bytes with Twox64Concat hasher) @@ -2809,8 +2642,6 @@ async fn handle_list_proposals( log_print!(" Total: {}", count.to_string().bright_yellow()); log_print!(" Active: {}", active_count.to_string().bright_green()); log_print!(" Approved: {}", approved_count.to_string().bright_yellow()); - log_print!(" Executed: {}", executed_count.to_string().bright_blue()); - log_print!(" Cancelled: {}", cancelled_count.to_string().bright_red()); } log_print!(""); @@ -2999,13 +2830,13 @@ async fn handle_high_security_status( log_success!("✅ High-Security: {}", "ENABLED".bright_green().bold()); log_print!(""); - // Convert interceptor to SS58 - let interceptor_bytes: &[u8; 32] = data.interceptor.as_ref(); - let interceptor_sp = SpAccountId32::from(*interceptor_bytes); - let interceptor_ss58 = interceptor_sp + // Convert guardian to SS58 + let guardian_bytes: &[u8; 32] = data.guardian.as_ref(); + let guardian_sp = SpAccountId32::from(*guardian_bytes); + let guardian_ss58 = guardian_sp .to_ss58check_with_version(sp_core::crypto::Ss58AddressFormat::custom(189)); - log_print!("🛡️ Guardian/Interceptor: {}", interceptor_ss58.bright_green().bold()); + log_print!("🛡️ Guardian: {}", guardian_ss58.bright_green().bold()); // Format delay display match data.delay { @@ -3200,7 +3031,7 @@ async fn handle_high_security_set( let propose_tx = quantus_subxt::api::tx() .multisig() - .propose(multisig_account_id, call_data, expiry); + .propose(multisig_account_id, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; diff --git a/src/cli/reversible.rs b/src/cli/reversible.rs index 993b8b2..a57f96d 100644 --- a/src/cli/reversible.rs +++ b/src/cli/reversible.rs @@ -460,8 +460,8 @@ async fn list_pending_transactions( log_print!(" 👤 To: {}", transfer_details.to.to_quantus_ss58()); log_print!(" 💰 Amount: {}", formatted_amount); log_print!( - " 🔄 Interceptor: {}", - transfer_details.interceptor.to_quantus_ss58() + " 🔄 Guardian: {}", + transfer_details.guardian.to_quantus_ss58() ); } } diff --git a/src/cli/wallet.rs b/src/cli/wallet.rs index 703b52d..7795e83 100644 --- a/src/cli/wallet.rs +++ b/src/cli/wallet.rs @@ -195,28 +195,28 @@ async fn fetch_high_security_status( return Ok(None); }; - let interceptor_ss58 = data.interceptor.to_quantus_ss58(); + let guardian_ss58 = data.guardian.to_quantus_ss58(); let delay_str = match data.delay { BlockNumberOrTimestamp::BlockNumber(blocks) => format!("{} blocks", blocks), BlockNumberOrTimestamp::Timestamp(ms) => format!("{} seconds", ms / 1000), }; - Ok(Some((interceptor_ss58, delay_str))) + Ok(Some((guardian_ss58, delay_str))) } -/// Fetch list of accounts for which this account is guardian (interceptor_index). +/// Fetch list of accounts for which this account is guardian (guardian_index). /// Returns an empty vec when the storage entry is absent (`None`), and an error on failure. async fn fetch_guardian_for_list( quantus_client: &crate::chain::client::QuantusClient, account_ss58: &str, ) -> crate::error::Result> { let account_id_sp = SpAccountId32::from_ss58check(account_ss58) - .map_err(|e| QuantusError::Generic(format!("Invalid SS58 for interceptor_index: {e:?}")))?; + .map_err(|e| QuantusError::Generic(format!("Invalid SS58 for guardian_index: {e:?}")))?; let account_bytes: [u8; 32] = *account_id_sp.as_ref(); let account_id = subxt::ext::subxt_core::utils::AccountId32::from(account_bytes); let storage_addr = quantus_subxt::api::storage() .reversible_transfers() - .interceptor_index(account_id); + .guardian_index(account_id); let latest = quantus_client.get_latest_block().await?; let value = quantus_client .client() @@ -224,10 +224,10 @@ async fn fetch_guardian_for_list( .at(latest) .fetch(&storage_addr) .await - .map_err(|e| QuantusError::NetworkError(format!("Fetch interceptor_index: {e:?}")))?; + .map_err(|e| QuantusError::NetworkError(format!("Fetch guardian_index: {e:?}")))?; - let list = value - .map(|bounded| bounded.0.iter().map(|a| a.to_quantus_ss58()).collect()) + let list: Vec = value + .map(|bounded| bounded.0.iter().map(|a: &subxt::ext::subxt_core::utils::AccountId32| a.to_quantus_ss58()).collect()) .unwrap_or_default(); Ok(list) } diff --git a/src/cli/wormhole.rs b/src/cli/wormhole.rs index 4406b02..6a8d724 100644 --- a/src/cli/wormhole.rs +++ b/src/cli/wormhole.rs @@ -2793,8 +2793,8 @@ struct DissolveOutput { /// Layer N: 2^(N-1) inputs → 2^N outputs (all below target_size) /// ``` /// -/// Each layer: batch inputs into groups of ≤DEFAULT_NUM_LEAF_PROOFS, generate proofs, aggregate, verify on-chain. -/// The final outputs are small enough to blend with the miner reward noise floor. +/// Each layer: batch inputs into groups of ≤DEFAULT_NUM_LEAF_PROOFS, generate proofs, aggregate, +/// verify on-chain. The final outputs are small enough to blend with the miner reward noise floor. #[allow(clippy::too_many_arguments)] async fn run_dissolve( amount: u128, diff --git a/src/lib.rs b/src/lib.rs index 998e595..4519bac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ pub use cli::send::{ // Re-export multisig functions for library usage pub use cli::multisig::{ - approve_dissolve_multisig, approve_proposal, cancel_proposal, create_multisig, + approve_proposal, cancel_proposal, create_multisig, get_multisig_info, get_proposal_info, list_proposals, parse_amount as parse_multisig_amount, predict_multisig_address, propose_custom, propose_transfer, MultisigInfo, ProposalInfo, ProposalStatus, diff --git a/src/quantus_metadata.scale b/src/quantus_metadata.scale index 74002ed6fa89073aa69d1f83c0223e40ce935997..2d3b5a17f16abe6e7b89573d0c720933472bb4f7 100644 GIT binary patch delta 16581 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 z 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 delta 11399 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 From 9b91a683b12810f69241f83eb66871a564305850 Mon Sep 17 00:00:00 2001 From: illuzen Date: Fri, 29 May 2026 11:57:37 +0900 Subject: [PATCH 3/5] update poseidon version and check leaf count for circuit binary regeneration --- Cargo.lock | 28 ++++++++++++++++++++-------- Cargo.toml | 5 ++--- build.rs | 7 +++++-- src/bins.rs | 22 +++++++++++++++++++++- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5897ea0..8ca0fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3646,7 +3646,7 @@ dependencies = [ "log", "parity-scale-codec", "qp-poseidon", - "qp-poseidon-core", + "qp-poseidon-core 1.5.0", "qp-rusty-crystals-dilithium", "qp-rusty-crystals-hdwallet", "scale-info", @@ -3772,7 +3772,7 @@ dependencies = [ "p3-goldilocks", "parity-scale-codec", "qp-poseidon-constants", - "qp-poseidon-core", + "qp-poseidon-core 1.5.0", "scale-info", "serde", "sp-core", @@ -3796,9 +3796,9 @@ dependencies = [ [[package]] name = "qp-poseidon-core" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51774769a44a1c65f9ad3959ff1497a9c315a16f5718151873721b3c5631413" +checksum = "e3117d3df79617ee2eb4d4576d2f76f6dbc9bf3f466d4477d188ee89acbd7b07" dependencies = [ "p3-field", "p3-goldilocks", @@ -3808,6 +3808,19 @@ dependencies = [ "rand_chacha 0.9.0", ] +[[package]] +name = "qp-poseidon-core" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882fbe1c3054d60ba863333f5c2d2cf30432204e16c014fcfd5dbae0a73217ee" +dependencies = [ + "p3-field", + "p3-goldilocks", + "p3-poseidon2", + "p3-symmetric", + "qp-poseidon-constants", +] + [[package]] name = "qp-rusty-crystals-dilithium" version = "2.4.0" @@ -3828,7 +3841,7 @@ dependencies = [ "hex", "hex-literal", "hmac 0.12.1", - "qp-poseidon-core", + "qp-poseidon-core 1.5.0", "qp-rusty-crystals-dilithium", "serde", "serde_json", @@ -3926,7 +3939,7 @@ dependencies = [ "hex", "qp-plonky2", "qp-poseidon-constants", - "qp-poseidon-core", + "qp-poseidon-core 1.5.0", "qp-wormhole-inputs", "rand 0.8.5", "serde", @@ -3951,8 +3964,7 @@ dependencies = [ "parity-scale-codec", "qp-dilithium-crypto", "qp-plonky2", - "qp-poseidon", - "qp-poseidon-core", + "qp-poseidon-core 2.0.2", "qp-rusty-crystals-dilithium", "qp-rusty-crystals-hdwallet", "qp-wormhole-aggregator", diff --git a/Cargo.toml b/Cargo.toml index 28ea575..33e5545 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,6 @@ rand = "0.9" # Quantus crypto dependencies (aligned with chain) qp-dilithium-crypto = { version = "0.3.1", features = ["serde"] } -qp-poseidon = { version = "1.4.0" } qp-rusty-crystals-dilithium = { version = "2.4.0" } qp-rusty-crystals-hdwallet = { version = "2.3.1" } @@ -92,11 +91,11 @@ qp-zk-circuits-common = { version = "2.0.1", default-features = false, features [build-dependencies] hex = "0.4" -qp-poseidon-core = "1.4.0" +qp-poseidon-core = "2.0.2" qp-wormhole-circuit-builder = { version = "2.0.1" } [dev-dependencies] -qp-poseidon-core = "1.4.0" +qp-poseidon-core = "2.0.2" serial_test = "3.1" tempfile = "3.8.1" diff --git a/build.rs b/build.rs index d9bda18..9c681b6 100644 --- a/build.rs +++ b/build.rs @@ -56,8 +56,11 @@ fn main() { .map(|v| v.parse().expect("QP_NUM_LEAF_PROOFS must be a valid usize")) .unwrap_or(DEFAULT_NUM_LEAF_PROOFS); - // Don't emit any rerun-if-changed directives - this forces the build script - // to run on every build. Circuit generation is fast enough in release mode. + // Always rebuild circuits on every build (~2s). Write a timestamp to a trigger + // file and tell Cargo to watch it - since we just wrote it, it's always "changed". + let trigger = Path::new(&out_dir).join(".rebuild-trigger"); + std::fs::write(&trigger, format!("{:?}", Instant::now())).ok(); + println!("cargo:rerun-if-changed={}", trigger.display()); println!( "cargo:warning=[quantus-cli] Generating ZK circuit binaries (num_leaf_proofs={})...", diff --git a/src/bins.rs b/src/bins.rs index a526449..42371c9 100644 --- a/src/bins.rs +++ b/src/bins.rs @@ -80,8 +80,28 @@ fn is_ready(dir: &Path) -> bool { if !REQUIRED_FILES.iter().all(|f| dir.join(f).exists()) { return false; } - match std::fs::read_to_string(dir.join(VERSION_MARKER)) { + // Check CLI version matches + let version_ok = match std::fs::read_to_string(dir.join(VERSION_MARKER)) { Ok(v) => v.trim() == env!("CARGO_PKG_VERSION"), + Err(_) => return false, + }; + if !version_ok { + return false; + } + // Check num_leaf_proofs in config.json matches current setting + let config_path = dir.join("config.json"); + match std::fs::read_to_string(&config_path) { + Ok(content) => { + // Parse just the num_leaf_proofs field to avoid pulling in full config dependency + #[derive(serde::Deserialize)] + struct ConfigCheck { + num_leaf_proofs: usize, + } + match serde_json::from_str::(&content) { + Ok(config) => config.num_leaf_proofs == env_num_leaf_proofs(), + Err(_) => false, + } + }, Err(_) => false, } } From 2525b29e3a66e62c11c5028eabc1b9d0ba499a45 Mon Sep 17 00:00:00 2001 From: illuzen Date: Fri, 29 May 2026 11:57:44 +0900 Subject: [PATCH 4/5] fmt --- src/cli/multisig.rs | 41 +++++++++++++++++++++++++---------------- src/cli/wallet.rs | 13 +++++++++---- src/lib.rs | 7 +++---- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/cli/multisig.rs b/src/cli/multisig.rs index 3a7e96e..906f50a 100644 --- a/src/cli/multisig.rs +++ b/src/cli/multisig.rs @@ -581,8 +581,11 @@ pub async fn propose_transfer( Compact(amount).encode_to(&mut call_data); // Build propose transaction - let propose_tx = - quantus_subxt::api::tx().multisig().propose(multisig_address, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); + let propose_tx = quantus_subxt::api::tx().multisig().propose( + multisig_address, + quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), + expiry, + ); // Submit transaction let execution_mode = ExecutionMode { finalized: false, wait_for_transaction: false }; @@ -611,8 +614,11 @@ pub async fn propose_custom( expiry: u32, ) -> crate::error::Result { // Build propose transaction - let propose_tx = - quantus_subxt::api::tx().multisig().propose(multisig_address, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); + let propose_tx = quantus_subxt::api::tx().multisig().propose( + multisig_address, + quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), + expiry, + ); // Submit transaction let execution_mode = ExecutionMode { finalized: false, wait_for_transaction: false }; @@ -1544,10 +1550,11 @@ async fn handle_propose( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Build transaction - let propose_tx = - quantus_subxt::api::tx() - .multisig() - .propose(multisig_address.clone(), quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); + let propose_tx = quantus_subxt::api::tx().multisig().propose( + multisig_address.clone(), + quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), + expiry, + ); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; @@ -1612,10 +1619,11 @@ async fn handle_propose_with_call_data( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Build transaction - let propose_tx = - quantus_subxt::api::tx() - .multisig() - .propose(multisig_account_id, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); + let propose_tx = quantus_subxt::api::tx().multisig().propose( + multisig_account_id, + quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), + expiry, + ); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; @@ -3028,10 +3036,11 @@ async fn handle_high_security_set( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Build propose transaction - let propose_tx = - quantus_subxt::api::tx() - .multisig() - .propose(multisig_account_id, quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), expiry); + let propose_tx = quantus_subxt::api::tx().multisig().propose( + multisig_account_id, + quantus_subxt::api::runtime_types::bounded_collections::bounded_vec::BoundedVec(call_data), + expiry, + ); // Always wait for transaction confirmation let propose_execution_mode = ExecutionMode { wait_for_transaction: true, ..execution_mode }; diff --git a/src/cli/wallet.rs b/src/cli/wallet.rs index 7795e83..38f0227 100644 --- a/src/cli/wallet.rs +++ b/src/cli/wallet.rs @@ -214,9 +214,8 @@ async fn fetch_guardian_for_list( let account_bytes: [u8; 32] = *account_id_sp.as_ref(); let account_id = subxt::ext::subxt_core::utils::AccountId32::from(account_bytes); - let storage_addr = quantus_subxt::api::storage() - .reversible_transfers() - .guardian_index(account_id); + let storage_addr = + quantus_subxt::api::storage().reversible_transfers().guardian_index(account_id); let latest = quantus_client.get_latest_block().await?; let value = quantus_client .client() @@ -227,7 +226,13 @@ async fn fetch_guardian_for_list( .map_err(|e| QuantusError::NetworkError(format!("Fetch guardian_index: {e:?}")))?; let list: Vec = value - .map(|bounded| bounded.0.iter().map(|a: &subxt::ext::subxt_core::utils::AccountId32| a.to_quantus_ss58()).collect()) + .map(|bounded| { + bounded + .0 + .iter() + .map(|a: &subxt::ext::subxt_core::utils::AccountId32| a.to_quantus_ss58()) + .collect() + }) .unwrap_or_default(); Ok(list) } diff --git a/src/lib.rs b/src/lib.rs index 4519bac..dfad76e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,10 +35,9 @@ pub use cli::send::{ // Re-export multisig functions for library usage pub use cli::multisig::{ - approve_proposal, cancel_proposal, create_multisig, - get_multisig_info, get_proposal_info, list_proposals, parse_amount as parse_multisig_amount, - predict_multisig_address, propose_custom, propose_transfer, MultisigInfo, ProposalInfo, - ProposalStatus, + approve_proposal, cancel_proposal, create_multisig, get_multisig_info, get_proposal_info, + list_proposals, parse_amount as parse_multisig_amount, predict_multisig_address, + propose_custom, propose_transfer, MultisigInfo, ProposalInfo, ProposalStatus, }; // Re-export wormhole library functions for SDK usage From a6d23244f0374de5b34d8f934731454c698348ea Mon Sep 17 00:00:00 2001 From: illuzen Date: Fri, 29 May 2026 12:46:04 +0900 Subject: [PATCH 5/5] clippy and nits --- build.rs | 11 ++++++----- clippy.sh | 5 +++++ examples/multisig_library_usage.rs | 2 +- src/cli/multisig.rs | 6 ------ 4 files changed, 12 insertions(+), 12 deletions(-) create mode 100755 clippy.sh diff --git a/build.rs b/build.rs index 9c681b6..eec0cd1 100644 --- a/build.rs +++ b/build.rs @@ -56,11 +56,12 @@ fn main() { .map(|v| v.parse().expect("QP_NUM_LEAF_PROOFS must be a valid usize")) .unwrap_or(DEFAULT_NUM_LEAF_PROOFS); - // Always rebuild circuits on every build (~2s). Write a timestamp to a trigger - // file and tell Cargo to watch it - since we just wrote it, it's always "changed". - let trigger = Path::new(&out_dir).join(".rebuild-trigger"); - std::fs::write(&trigger, format!("{:?}", Instant::now())).ok(); - println!("cargo:rerun-if-changed={}", trigger.display()); + // No `cargo:rerun-if-changed` directives: Cargo uses default fingerprinting, + // re-running this script when any source file in the package changes. + // This ensures circuits are regenerated when bins_consts.rs (DEFAULT_NUM_LEAF_PROOFS) + // or any circuit-related code changes. For installed binaries, runtime detection + // in bins.rs `is_ready()` handles leaf count mismatches by regenerating on first use. + println!("cargo:rerun-if-env-changed=QP_NUM_LEAF_PROOFS"); println!( "cargo:warning=[quantus-cli] Generating ZK circuit binaries (num_leaf_proofs={})...", diff --git a/clippy.sh b/clippy.sh new file mode 100755 index 0000000..311d506 --- /dev/null +++ b/clippy.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Run the same clippy command as CI (see .github/workflows/ci.yml) +set -euo pipefail + +cargo clippy --workspace --all-targets --all-features --locked -- -D warnings diff --git a/examples/multisig_library_usage.rs b/examples/multisig_library_usage.rs index 7842e09..04d5423 100644 --- a/examples/multisig_library_usage.rs +++ b/examples/multisig_library_usage.rs @@ -84,7 +84,7 @@ async fn main() -> Result<()> { for (i, signer) in info.signers.iter().enumerate() { println!(" {}. {}", i + 1, signer); } - println!(" Active Proposals: {}", info.active_proposals); + println!(" Proposal Nonce: {}", info.proposal_nonce); println!(); } diff --git a/src/cli/multisig.rs b/src/cli/multisig.rs index 906f50a..0f025cf 100644 --- a/src/cli/multisig.rs +++ b/src/cli/multisig.rs @@ -876,12 +876,6 @@ pub async fn list_proposals( Ok(proposals) } -/// Approve dissolving a multisig -/// -/// Requires threshold approvals. When threshold is reached, multisig is dissolved. -/// Requirements: -/// - No proposals exist (active, executed, or cancelled) -/// - Multisig account balance must be zero // ============================================================================ // CLI HANDLERS (Internal) // ============================================================================