Skip to content
Snippets Groups Projects
utils.rs 1.85 KiB
Newer Older
use crate::*;

/// track progress of transaction on the network
/// until it is in block with success or failure
pub async fn track_progress(
	mut progress: TxProgress,
) -> Result<ExtrinsicEvents<Runtime>, subxt::Error> {
	loop {
		if let Some(status) = progress.next_item().await {
			match status? {
				TxStatus::Ready => {
					println!("transaction submitted to the network, waiting 6 seconds...");
				}
				TxStatus::InBlock(in_block) => break in_block,
				TxStatus::Invalid => {
					println!("Invalid");
				}
				_ => continue,
			}
		}
	}
	.wait_for_success()
	.await
}

/// generic extrinsic submitter
pub async fn submit_call_and_look_event<E: std::fmt::Debug + StaticEvent, Call: TxPayload>(
	data: &Data,
	call: &Call,
) -> Result<(), subxt::Error> {
	let progress = data
		.client()
		.tx()
		.sign_and_submit_then_watch(
			call,
			&PairSigner::new(data.keypair()),
			BaseExtrinsicParamsBuilder::new(),
		)
		.await?;

	if data.args.no_wait {
		return Ok(());
	}
	let events = track_progress(progress).await?;
	if let Some(e) = events.find_first::<E>()? {
		println!("{e:?}");
	}

	Ok(())
}

/// custom error type intended to provide more convenient error message to user
#[derive(Debug)]
pub enum GcliError {
	/// error coming from subxt
	Subxt(subxt::Error),
	/// error coming from duniter
	Duniter(String),
	/// error coming from indexer
	Indexer(String),
	/// logic error (illegal operation or security)
	Logic(String),
	/// error coming from anyhow
	Anyhow(anyhow::Error),
}
impl std::fmt::Display for GcliError {
	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
		write!(f, "{:?}", self)
	}
}
impl std::error::Error for GcliError {}
impl From<subxt::Error> for GcliError {
	fn from(e: subxt::Error) -> GcliError {
		GcliError::Subxt(e)
	}
}
impl From<anyhow::Error> for GcliError {
	fn from(e: anyhow::Error) -> GcliError {
		GcliError::Anyhow(e)
	}
}