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