Skip to content
Snippets Groups Projects
utils.rs 2.26 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> {
	// submit call
	let progress = submit_call(data, call).await?;
	// if no wait, return immediately
	if data.args.no_wait {
		return Ok(());
	}
	// collect events
	let events = track_progress(progress).await?;
	// print given event if there
	look_event::<E>(&events)
}

/// submit call
pub async fn submit_call<Call: TxPayload>(
	data: &Data,
	call: &Call,
) -> Result<TxProgress, subxt::Error> {
	data.client()
		.tx()
		.sign_and_submit_then_watch(
			call,
			&PairSigner::new(data.keypair()),
			BaseExtrinsicParamsBuilder::new(),
		)
/// look event
pub fn look_event<E: std::fmt::Debug + StaticEvent>(
	events: &ExtrinsicEvents<Runtime>,
) -> Result<(), subxt::Error> {
	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)
	}
}