1use crate::{
3 chain::quantus_subxt,
4 cli::{common::submit_transaction, progress_spinner::wait_for_tx_confirmation},
5 error::QuantusError,
6 log_error, log_print, log_success, log_verbose,
7};
8use clap::Subcommand;
9use colored::Colorize;
10use std::str::FromStr;
11
12#[derive(Subcommand, Debug)]
14pub enum ReferendaCommands {
15 SubmitRemark {
17 #[arg(long)]
19 message: String,
20
21 #[arg(short, long)]
23 from: String,
24
25 #[arg(short, long)]
27 password: Option<String>,
28
29 #[arg(long)]
31 password_file: Option<String>,
32
33 #[arg(long, default_value = "signed")]
35 origin: String,
36 },
37
38 Submit {
40 #[arg(long)]
42 preimage_hash: String,
43
44 #[arg(short, long)]
46 from: String,
47
48 #[arg(short, long)]
50 password: Option<String>,
51
52 #[arg(long)]
54 password_file: Option<String>,
55
56 #[arg(long, default_value = "signed")]
58 origin: String,
59 },
60
61 List,
63
64 Get {
66 #[arg(short, long)]
68 index: u32,
69
70 #[arg(long)]
72 decode: bool,
73 },
74
75 Status {
77 #[arg(short, long)]
79 index: u32,
80 },
81
82 PlaceDecisionDeposit {
84 #[arg(short, long)]
86 index: u32,
87
88 #[arg(short, long)]
90 from: String,
91
92 #[arg(short, long)]
94 password: Option<String>,
95
96 #[arg(long)]
98 password_file: Option<String>,
99 },
100
101 Vote {
103 #[arg(short, long)]
105 index: u32,
106
107 #[arg(long)]
109 aye: bool,
110
111 #[arg(long, default_value = "0")]
113 conviction: u8,
114
115 #[arg(long)]
117 amount: String,
118
119 #[arg(short, long)]
121 from: String,
122
123 #[arg(short, long)]
125 password: Option<String>,
126
127 #[arg(long)]
129 password_file: Option<String>,
130 },
131
132 RefundSubmissionDeposit {
134 #[arg(short, long)]
136 index: u32,
137
138 #[arg(short, long)]
140 from: String,
141
142 #[arg(short, long)]
144 password: Option<String>,
145
146 #[arg(long)]
148 password_file: Option<String>,
149 },
150
151 RefundDecisionDeposit {
153 #[arg(short, long)]
155 index: u32,
156
157 #[arg(short, long)]
159 from: String,
160
161 #[arg(short, long)]
163 password: Option<String>,
164
165 #[arg(long)]
167 password_file: Option<String>,
168 },
169
170 Config,
172}
173
174pub async fn handle_referenda_command(
176 command: ReferendaCommands,
177 node_url: &str,
178) -> crate::error::Result<()> {
179 let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?;
180
181 match command {
182 ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } =>
183 submit_remark_proposal(
184 &quantus_client,
185 &message,
186 &from,
187 password,
188 password_file,
189 &origin,
190 )
191 .await,
192 ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } =>
193 submit_proposal(
194 &quantus_client,
195 &preimage_hash,
196 &from,
197 password,
198 password_file,
199 &origin,
200 )
201 .await,
202 ReferendaCommands::List => list_proposals(&quantus_client).await,
203 ReferendaCommands::Get { index, decode } =>
204 get_proposal_details(&quantus_client, index, decode).await,
205 ReferendaCommands::Status { index } => get_proposal_status(&quantus_client, index).await,
206 ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } =>
207 place_decision_deposit(&quantus_client, index, &from, password, password_file).await,
208 ReferendaCommands::Vote {
209 index,
210 aye,
211 conviction,
212 amount,
213 from,
214 password,
215 password_file,
216 } =>
217 vote_on_referendum(
218 &quantus_client,
219 index,
220 aye,
221 conviction,
222 &amount,
223 &from,
224 password,
225 password_file,
226 )
227 .await,
228 ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } =>
229 refund_submission_deposit(&quantus_client, index, &from, password, password_file).await,
230 ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } =>
231 refund_decision_deposit(&quantus_client, index, &from, password, password_file).await,
232 ReferendaCommands::Config => get_config(&quantus_client).await,
233 }
234}
235
236async fn submit_remark_proposal(
238 quantus_client: &crate::chain::client::QuantusClient,
239 message: &str,
240 from: &str,
241 password: Option<String>,
242 password_file: Option<String>,
243 origin_type: &str,
244) -> crate::error::Result<()> {
245 use qp_poseidon::PoseidonHasher;
246
247 log_print!("đ Submitting System::remark Proposal to Referenda");
248 log_print!(" đŦ Message: {}", message.bright_cyan());
249 log_print!(" đ Submitted by: {}", from.bright_yellow());
250 log_print!(" đ¯ Origin type: {}", origin_type.bright_magenta());
251
252 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
254
255 let remark_bytes = message.as_bytes().to_vec();
257 let remark_payload = quantus_subxt::api::tx().system().remark(remark_bytes.clone());
258 let metadata = quantus_client.client().metadata();
259 let encoded_call = <_ as subxt::tx::Payload>::encode_call_data(&remark_payload, &metadata)
260 .map_err(|e| QuantusError::Generic(format!("Failed to encode call data: {:?}", e)))?;
261
262 log_verbose!("đ Encoded call size: {} bytes", encoded_call.len());
263
264 let preimage_hash: sp_core::H256 =
266 <PoseidonHasher as sp_runtime::traits::Hash>::hash(&encoded_call);
267
268 log_print!("đ Preimage hash: {:?}", preimage_hash);
269
270 type PreimageBytes = quantus_subxt::api::preimage::calls::types::note_preimage::Bytes;
272 let bounded_bytes: PreimageBytes = encoded_call.clone();
273
274 log_print!("đ Submitting preimage...");
275 let note_preimage_tx = quantus_subxt::api::tx().preimage().note_preimage(bounded_bytes);
276 let preimage_tx_hash =
277 submit_transaction(quantus_client, &keypair, note_preimage_tx, None).await?;
278 log_print!("â
Preimage transaction submitted: {:?}", preimage_tx_hash);
279
280 log_print!("âŗ Waiting for preimage transaction confirmation...");
282 let _ = wait_for_tx_confirmation(quantus_client.client(), preimage_tx_hash).await?;
283 log_print!("â
Preimage transaction confirmed!");
284
285 type ProposalBounded =
287 quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded<
288 quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall,
289 quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher,
290 >;
291
292 let preimage_hash_subxt: subxt::utils::H256 = preimage_hash;
293 let proposal: ProposalBounded =
294 ProposalBounded::Lookup { hash: preimage_hash_subxt, len: encoded_call.len() as u32 };
295
296 let account_id_sp = keypair.to_account_id_32();
298 let account_id_subxt: subxt::ext::subxt_core::utils::AccountId32 =
299 subxt::ext::subxt_core::utils::AccountId32(*account_id_sp.as_ref());
300
301 let origin_caller = match origin_type.to_lowercase().as_str() {
302 "signed" => {
303 let raw_origin =
304 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Signed(
305 account_id_subxt,
306 );
307 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
308 },
309 "none" => {
310 let raw_origin =
311 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::None;
312 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
313 },
314 "root" => {
315 let raw_origin =
316 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root;
317 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
318 },
319 _ =>
320 return Err(QuantusError::Generic(format!(
321 "Invalid origin type: {}. Must be 'signed', 'none', or 'root'",
322 origin_type
323 ))),
324 };
325
326 let enactment =
327 quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After(
328 10u32, );
330
331 log_print!("đ§ Creating Referenda::submit call...");
332 let submit_call =
333 quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment);
334
335 let tx_hash = submit_transaction(quantus_client, &keypair, submit_call, None).await?;
336 log_print!(
337 "â
{} Referendum proposal submitted! Hash: {:?}",
338 "SUCCESS".bright_green().bold(),
339 tx_hash
340 );
341
342 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
343 log_success!("đ {} Proposal created!", "FINISHED".bright_green().bold());
344 log_print!("đĄ Use 'quantus referenda list' to see active proposals");
345 Ok(())
346}
347
348async fn submit_proposal(
350 quantus_client: &crate::chain::client::QuantusClient,
351 preimage_hash: &str,
352 from: &str,
353 password: Option<String>,
354 password_file: Option<String>,
355 origin_type: &str,
356) -> crate::error::Result<()> {
357 log_print!("đ Submitting Proposal to Referenda");
358 log_print!(" đ Preimage hash: {}", preimage_hash.bright_cyan());
359 log_print!(" đ Submitted by: {}", from.bright_yellow());
360 log_print!(" đ¯ Origin type: {}", origin_type.bright_magenta());
361
362 let hash_str = preimage_hash.trim_start_matches("0x");
364 let preimage_hash_parsed: sp_core::H256 = sp_core::H256::from_str(hash_str)
365 .map_err(|_| QuantusError::Generic("Invalid preimage hash format".to_string()))?;
366
367 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
369
370 log_print!("đ Checking preimage status...");
372 let latest_block_hash = quantus_client.get_latest_block().await?;
373 let storage_at = quantus_client.client().storage().at(latest_block_hash);
374
375 let preimage_status = storage_at
376 .fetch(
377 &quantus_subxt::api::storage()
378 .preimage()
379 .request_status_for(preimage_hash_parsed),
380 )
381 .await
382 .map_err(|e| QuantusError::Generic(format!("Failed to fetch preimage status: {:?}", e)))?
383 .ok_or_else(|| QuantusError::Generic("Preimage not found on chain".to_string()))?;
384
385 let preimage_len = match preimage_status {
386 quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Unrequested {
387 ticket: _,
388 len,
389 } => len,
390 quantus_subxt::api::runtime_types::pallet_preimage::RequestStatus::Requested {
391 maybe_ticket: _,
392 count: _,
393 maybe_len,
394 } => match maybe_len {
395 Some(len) => len,
396 None => return Err(QuantusError::Generic("Preimage length not available".to_string())),
397 },
398 };
399
400 log_print!("â
Preimage found! Length: {} bytes", preimage_len);
401
402 type ProposalBounded =
404 quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded<
405 quantus_subxt::api::runtime_types::quantus_runtime::RuntimeCall,
406 quantus_subxt::api::runtime_types::qp_poseidon::PoseidonHasher,
407 >;
408
409 let preimage_hash_subxt: subxt::utils::H256 = preimage_hash_parsed;
410 let proposal: ProposalBounded =
411 ProposalBounded::Lookup { hash: preimage_hash_subxt, len: preimage_len };
412
413 let account_id_sp = keypair.to_account_id_32();
415 let account_id_subxt: subxt::ext::subxt_core::utils::AccountId32 =
416 subxt::ext::subxt_core::utils::AccountId32(*account_id_sp.as_ref());
417
418 let origin_caller = match origin_type.to_lowercase().as_str() {
419 "signed" => {
420 let raw_origin =
421 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Signed(
422 account_id_subxt,
423 );
424 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
425 },
426 "none" => {
427 let raw_origin =
428 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::None;
429 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
430 },
431 "root" => {
432 let raw_origin =
433 quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root;
434 quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin)
435 },
436 _ =>
437 return Err(QuantusError::Generic(format!(
438 "Invalid origin type: {}. Must be 'signed', 'none', or 'root'",
439 origin_type
440 ))),
441 };
442
443 let enactment =
444 quantus_subxt::api::runtime_types::frame_support::traits::schedule::DispatchTime::After(
445 10u32,
446 );
447
448 log_print!("đ§ Creating Referenda::submit call...");
449 let submit_call =
450 quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment);
451
452 let tx_hash = submit_transaction(quantus_client, &keypair, submit_call, None).await?;
453 log_print!(
454 "â
{} Referendum proposal submitted! Hash: {:?}",
455 "SUCCESS".bright_green().bold(),
456 tx_hash
457 );
458
459 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
460 log_success!("đ {} Proposal created!", "FINISHED".bright_green().bold());
461 log_print!("đĄ Use 'quantus referenda list' to see active proposals");
462 Ok(())
463}
464
465async fn list_proposals(
467 quantus_client: &crate::chain::client::QuantusClient,
468) -> crate::error::Result<()> {
469 log_print!("đ Active Referenda Proposals");
470 log_print!("");
471
472 let addr = quantus_subxt::api::storage().referenda().referendum_count();
473
474 let latest_block_hash = quantus_client.get_latest_block().await?;
475 let storage_at = quantus_client.client().storage().at(latest_block_hash);
476
477 let count = storage_at.fetch(&addr).await?;
478
479 if let Some(total) = count {
480 log_print!("đ Total referenda created: {}", total);
481 if total == 0 {
482 log_print!("đ No active proposals found");
483 return Ok(());
484 }
485 log_print!("đ Fetching recent referenda...");
486 for i in (0..total).rev().take(10) {
487 get_proposal_status(quantus_client, i).await?;
488 log_print!("----------------------------------------");
489 }
490 } else {
491 log_print!("đ No referenda found - Referenda may be empty");
492 }
493
494 Ok(())
495}
496
497async fn get_proposal_details(
499 quantus_client: &crate::chain::client::QuantusClient,
500 index: u32,
501 decode: bool,
502) -> crate::error::Result<()> {
503 use quantus_subxt::api::runtime_types::pallet_referenda::types::ReferendumInfo;
504
505 log_print!("đ Referendum #{} Details", index);
506 log_print!("");
507
508 let addr = quantus_subxt::api::storage().referenda().referendum_info_for(index);
509
510 let latest_block_hash = quantus_client.get_latest_block().await?;
511 let storage_at = quantus_client.client().storage().at(latest_block_hash);
512
513 let info = storage_at.fetch(&addr).await?;
514
515 if let Some(referendum_info) = info {
516 if decode {
517 match &referendum_info {
519 ReferendumInfo::Ongoing(status) => {
520 log_print!("đ {} Referendum #{}", "Ongoing".bright_green(), index);
521 log_print!(" đ¤ī¸ Track: {}", status.track);
522 log_print!(" đ
Submitted: Block #{}", status.submitted);
523 log_print!(
524 " đŗī¸ Tally: Ayes: {}, Nays: {}, Support: {}",
525 status.tally.ayes,
526 status.tally.nays,
527 status.tally.support
528 );
529 log_print!("");
530
531 if let quantus_subxt::api::runtime_types::frame_support::traits::preimages::Bounded::Lookup {
533 hash,
534 len,
535 } = &status.proposal
536 {
537 log_print!("đ Proposal Details:");
538 log_print!(" đ Preimage Hash: {:?}", hash);
539 log_print!(" đ Length: {} bytes", len);
540 log_print!("");
541
542 match crate::cli::referenda_decode::decode_preimage(quantus_client, hash, *len).await {
544 Ok(decoded) => {
545 log_print!("â
Decoded Proposal:");
546 log_print!("{}", decoded);
547 },
548 Err(e) => {
549 log_print!("â ī¸ Could not decode proposal: {}", e);
550 log_print!(" Run 'quantus preimage get --hash {:?} --len {}' to see raw data", hash, len);
551 },
552 }
553 } else {
554 log_print!("â ī¸ Proposal is inline (not a preimage lookup)");
555 }
556 },
557 ReferendumInfo::Approved(..) => {
558 log_print!("đ {} Referendum #{}", "Approved".green(), index);
559 log_print!(
560 " âšī¸ Proposal details no longer available (referendum finalized)"
561 );
562 },
563 ReferendumInfo::Rejected(..) => {
564 log_print!("đ {} Referendum #{}", "Rejected".red(), index);
565 log_print!(
566 " âšī¸ Proposal details no longer available (referendum finalized)"
567 );
568 },
569 ReferendumInfo::Cancelled(..) => {
570 log_print!("đ {} Referendum #{}", "Cancelled".yellow(), index);
571 log_print!(
572 " âšī¸ Proposal details no longer available (referendum finalized)"
573 );
574 },
575 ReferendumInfo::TimedOut(..) => {
576 log_print!("đ {} Referendum #{}", "TimedOut".dimmed(), index);
577 log_print!(
578 " âšī¸ Proposal details no longer available (referendum finalized)"
579 );
580 },
581 ReferendumInfo::Killed(..) => {
582 log_print!("đ {} Referendum #{}", "Killed".red().bold(), index);
583 log_print!(" âšī¸ Proposal details no longer available (referendum killed)");
584 },
585 }
586 } else {
587 log_print!("đ Referendum Information (raw):");
589 log_print!("{:#?}", referendum_info);
590 }
591 } else {
592 log_print!("đ Referendum #{} not found", index);
593 }
594 Ok(())
595}
596
597async fn get_proposal_status(
599 quantus_client: &crate::chain::client::QuantusClient,
600 index: u32,
601) -> crate::error::Result<()> {
602 use quantus_subxt::api::runtime_types::pallet_referenda::types::ReferendumInfo;
603
604 log_verbose!("đ Fetching status for Referendum #{}...", index);
605
606 let addr = quantus_subxt::api::storage().referenda().referendum_info_for(index);
607
608 let latest_block_hash = quantus_client.get_latest_block().await?;
609 let storage_at = quantus_client.client().storage().at(latest_block_hash);
610
611 let info_res = storage_at.fetch(&addr).await;
612
613 match info_res {
614 Ok(Some(info)) => {
615 log_print!("đ Status for Referendum #{}", index.to_string().bright_yellow());
616 match info {
617 ReferendumInfo::Ongoing(status) => {
618 log_print!(" - Status: {}", "Ongoing".bright_green());
619 log_print!(" - Track: {}", status.track);
620 log_print!(" - Submitted at: block {}", status.submitted);
621 log_print!(
622 " - Tally: Ayes: {}, Nays: {}",
623 status.tally.ayes,
624 status.tally.nays
625 );
626 log_verbose!(" - Full status: {:#?}", status);
627 },
628 ReferendumInfo::Approved(submitted, ..) => {
629 log_print!(" - Status: {}", "Approved".green());
630 log_print!(" - Submitted at block: {}", submitted);
631 },
632 ReferendumInfo::Rejected(submitted, ..) => {
633 log_print!(" - Status: {}", "Rejected".red());
634 log_print!(" - Submitted at block: {}", submitted);
635 },
636 ReferendumInfo::Cancelled(submitted, ..) => {
637 log_print!(" - Status: {}", "Cancelled".yellow());
638 log_print!(" - Submitted at block: {}", submitted);
639 },
640 ReferendumInfo::TimedOut(submitted, ..) => {
641 log_print!(" - Status: {}", "TimedOut".dimmed());
642 log_print!(" - Submitted at block: {}", submitted);
643 },
644 ReferendumInfo::Killed(submitted) => {
645 log_print!(" - Status: {}", "Killed".red().bold());
646 log_print!(" - Killed at block: {}", submitted);
647 },
648 }
649 },
650 Ok(None) => log_print!("đ Referendum #{} not found", index),
651 Err(e) => log_error!("â Failed to fetch referendum #{}: {:?}", index, e),
652 }
653
654 Ok(())
655}
656
657async fn place_decision_deposit(
659 quantus_client: &crate::chain::client::QuantusClient,
660 index: u32,
661 from: &str,
662 password: Option<String>,
663 password_file: Option<String>,
664) -> crate::error::Result<()> {
665 log_print!("đ Placing decision deposit for Referendum #{}", index);
666 log_print!(" đ Placed by: {}", from.bright_yellow());
667
668 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
669
670 let deposit_call = quantus_subxt::api::tx().referenda().place_decision_deposit(index);
671 let tx_hash = submit_transaction(quantus_client, &keypair, deposit_call, None).await?;
672 log_success!("â
Decision deposit placed! Hash: {:?}", tx_hash.to_string().bright_yellow());
673 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
674 Ok(())
675}
676
677async fn vote_on_referendum(
679 quantus_client: &crate::chain::client::QuantusClient,
680 index: u32,
681 aye: bool,
682 conviction: u8,
683 amount: &str,
684 from: &str,
685 password: Option<String>,
686 password_file: Option<String>,
687) -> crate::error::Result<()> {
688 log_print!("đŗī¸ Voting on Referendum #{}", index);
689 log_print!(" đ Vote: {}", if aye { "AYE â
".bright_green() } else { "NAY â".bright_red() });
690 log_print!(" đ° Amount: {}", amount.bright_cyan());
691 log_print!(" đ Conviction: {}", conviction);
692 log_print!(" đ Signed by: {}", from.bright_yellow());
693
694 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
695
696 let amount_value: u128 = (amount
698 .parse::<f64>()
699 .map_err(|_| QuantusError::Generic("Invalid amount format".to_string()))?
700 .max(0.0) *
701 1_000_000_000_000_000_000.0) as u128;
702
703 if conviction > 6 {
705 return Err(QuantusError::Generic("Invalid conviction (must be 0-6)".to_string()));
706 }
707
708 let vote =
710 quantus_subxt::api::runtime_types::pallet_conviction_voting::vote::AccountVote::Standard {
711 vote: quantus_subxt::api::runtime_types::pallet_conviction_voting::vote::Vote(
712 if aye { 128 } else { 0 } | conviction,
713 ),
714 balance: amount_value,
715 };
716
717 let vote_call = quantus_subxt::api::tx().conviction_voting().vote(index, vote);
718 let tx_hash = submit_transaction(quantus_client, &keypair, vote_call, None).await?;
719
720 log_print!(
721 "â
{} Vote transaction submitted! Hash: {:?}",
722 "SUCCESS".bright_green().bold(),
723 tx_hash
724 );
725
726 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
727 log_success!("đ {} Vote submitted!", "FINISHED".bright_green().bold());
728 Ok(())
729}
730
731async fn get_config(
733 quantus_client: &crate::chain::client::QuantusClient,
734) -> crate::error::Result<()> {
735 log_print!("âī¸ Referenda Configuration");
736 log_print!("");
737
738 let constants = quantus_client.client().constants();
739 let tracks_addr = quantus_subxt::api::constants().referenda().tracks();
740
741 match constants.at(&tracks_addr) {
742 Ok(tracks) => {
743 log_print!("{}", "đ Track Configuration:".bold());
744 for (id, info) in tracks.iter() {
745 log_print!(" ------------------------------------");
746 log_print!(
747 " âĸ {} #{}: {}",
748 "Track".bold(),
749 id,
750 info.name.to_string().bright_cyan()
751 );
752 log_print!(" âĸ Max Deciding: {}", info.max_deciding);
753 log_print!(" âĸ Decision Deposit: {}", info.decision_deposit);
754 log_print!(" âĸ Prepare Period: {} blocks", info.prepare_period);
755 log_print!(" âĸ Decision Period: {} blocks", info.decision_period);
756 log_print!(" âĸ Confirm Period: {} blocks", info.confirm_period);
757 log_print!(" âĸ Min Enactment Period: {} blocks", info.min_enactment_period);
758 }
759 log_print!(" ------------------------------------");
760 },
761 Err(e) => {
762 log_error!("â Failed to decode Tracks constant: {:?}", e);
763 log_print!("đĄ It's possible the Tracks constant is not in the expected format.");
764 },
765 }
766
767 Ok(())
768}
769
770async fn refund_submission_deposit(
772 quantus_client: &crate::chain::client::QuantusClient,
773 index: u32,
774 from: &str,
775 password: Option<String>,
776 password_file: Option<String>,
777) -> crate::error::Result<()> {
778 log_print!("đ° Refunding submission deposit for Referendum #{}", index);
779 log_print!(" đ Refund to: {}", from.bright_yellow());
780
781 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
783
784 let refund_call = quantus_subxt::api::tx().referenda().refund_submission_deposit(index);
786
787 let tx_hash = submit_transaction(quantus_client, &keypair, refund_call, None).await?;
788 log_print!(
789 "â
{} Refund transaction submitted! Hash: {:?}",
790 "SUCCESS".bright_green().bold(),
791 tx_hash
792 );
793
794 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
795 log_success!("đ {} Submission deposit refunded!", "FINISHED".bright_green().bold());
796 log_print!("đĄ Check your balance to confirm the refund");
797 Ok(())
798}
799
800async fn refund_decision_deposit(
802 quantus_client: &crate::chain::client::QuantusClient,
803 index: u32,
804 from: &str,
805 password: Option<String>,
806 password_file: Option<String>,
807) -> crate::error::Result<()> {
808 log_print!("đ° Refunding decision deposit for Referendum #{}", index);
809 log_print!(" đ Refund to: {}", from.bright_yellow());
810
811 let keypair = crate::wallet::load_keypair_from_wallet(from, password, password_file)?;
813
814 let refund_call = quantus_subxt::api::tx().referenda().refund_decision_deposit(index);
816
817 let tx_hash = submit_transaction(quantus_client, &keypair, refund_call, None).await?;
818 log_print!(
819 "â
{} Refund transaction submitted! Hash: {:?}",
820 "SUCCESS".bright_green().bold(),
821 tx_hash
822 );
823
824 let _ = wait_for_tx_confirmation(quantus_client.client(), tx_hash).await?;
825 log_success!("đ {} Decision deposit refunded!", "FINISHED".bright_green().bold());
826 log_print!("đĄ Check your balance to confirm the refund");
827 Ok(())
828}