diff --git a/src/commands/collective.rs b/src/commands/collective.rs
index ea4b0f4b7c1d0562e732edcaa3edc8b7187c6dac..d9645be0ae3b9ec69093548bb6007639188ec916 100644
--- a/src/commands/collective.rs
+++ b/src/commands/collective.rs
@@ -85,8 +85,8 @@ pub async fn technical_committee_vote(
 	proposal_hash: H256,
 	proposal_index: u32,
 	vote: bool,
-) -> Result<TxProgress, subxt::Error> {
-	client
+) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx()
@@ -95,5 +95,13 @@ pub async fn technical_committee_vote(
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+
+	if let Some(e) = events.find_first::<runtime::technical_committee::events::Voted>()? {
+		println!("{e:?}");
+	}
+
+	Ok(())
 }
diff --git a/src/commands/identity.rs b/src/commands/identity.rs
index 7b9ea24008f6e3dfba6441aafe434608eb83c17f..0a3a4308b3049eb68c83391ae17ff8191cdc78ac 100644
--- a/src/commands/identity.rs
+++ b/src/commands/identity.rs
@@ -96,34 +96,46 @@ pub async fn create_identity(
 	pair: Pair,
 	client: &Client,
 	target: AccountId32,
-) -> Result<TxProgress, subxt::Error> {
-	client
+) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().create_identity(target),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) = events.find_first::<runtime::identity::events::IdtyCreated>()? {
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
 pub async fn confirm_identity(
 	pair: Pair,
 	client: &Client,
 	name: String,
-) -> Result<TxProgress, subxt::Error> {
-	client
+) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().confirm_identity(name),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) = events.find_first::<runtime::identity::events::IdtyConfirmed>()? {
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
 /// generate revokation document and submit it immediately
-pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> {
+pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> {
 	let (_payload, signature) = generate_revoc_doc(&data);
 
 	// Transform signature to MultiSignature
@@ -131,7 +143,8 @@ pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> {
 	let signature = Signature(signature.0);
 	let multisign = MultiSignature::Sr25519(signature);
 
-	data.client()
+	let progress = data
+		.client()
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx()
@@ -140,5 +153,11 @@ pub async fn revoke_identity(data: Data) -> Result<TxProgress, subxt::Error> {
 			&PairSigner::new(data.keypair()),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) = events.find_first::<runtime::identity::events::IdtyRemoved>()? {
+		println!("{e:?}");
+	}
+	Ok(())
 }
diff --git a/src/commands/oneshot.rs b/src/commands/oneshot.rs
index 70f579646a26dbcae23e762d521f8fb061b2473d..8b56affc8f561a823a776e395060555e60e0693a 100644
--- a/src/commands/oneshot.rs
+++ b/src/commands/oneshot.rs
@@ -8,8 +8,8 @@ pub async fn create_oneshot_account(
 	client: &Client,
 	balance: u64,
 	dest: AccountId32,
-) -> Result<TxProgress, subxt::Error> {
-	client
+) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx()
@@ -18,7 +18,15 @@ pub async fn create_oneshot_account(
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) =
+		events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()?
+	{
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
 pub async fn consume_oneshot_account(
@@ -26,13 +34,13 @@ pub async fn consume_oneshot_account(
 	client: &Client,
 	dest: AccountId32,
 	dest_oneshot: bool,
-) -> Result<TxProgress, subxt::Error> {
+) -> Result<(), subxt::Error> {
 	let number = client
 		.storage()
 		.fetch(&runtime::storage().system().number(), None)
 		.await?
 		.unwrap();
-	client
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().oneshot_account().consume_oneshot_account(
@@ -50,7 +58,15 @@ pub async fn consume_oneshot_account(
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) =
+		events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()?
+	{
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
 pub async fn consume_oneshot_account_with_remaining(
@@ -61,13 +77,13 @@ pub async fn consume_oneshot_account_with_remaining(
 	dest_oneshot: bool,
 	remaining_to: AccountId32,
 	remaining_to_oneshot: bool,
-) -> Result<TxProgress, subxt::Error> {
+) -> Result<(), subxt::Error> {
 	let number = client
 		.storage()
 		.fetch(&runtime::storage().system().number(), None)
 		.await?
 		.unwrap();
-	client
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx()
@@ -97,10 +113,21 @@ pub async fn consume_oneshot_account_with_remaining(
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) =
+		events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
+	{
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
-pub async fn oneshot_account_balance(client: &Client, account: AccountId32) -> Result<(), anyhow::Error> {
+pub async fn oneshot_account_balance(
+	client: &Client,
+	account: AccountId32,
+) -> Result<(), anyhow::Error> {
 	log::info!(
 		"{}",
 		client
diff --git a/src/commands/smith.rs b/src/commands/smith.rs
index e9d89b7e62e3425f2ce1cc5309354f9ddfce5b3b..bc2fd052dddaa6e5e5161d6b29c165d78e1c6f19 100644
--- a/src/commands/smith.rs
+++ b/src/commands/smith.rs
@@ -2,10 +2,11 @@ use crate::*;
 
 use sp_core::{crypto::AccountId32, sr25519::Pair, Pair as _};
 use std::ops::Deref;
-use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner, TxStatus};
+use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner};
 
 type SessionKeys = [u8; 128];
 
+/// rotate session keys
 pub async fn rotate_keys(client: &Client) -> Result<SessionKeys, anyhow::Error> {
 	client
 		.rpc()
@@ -16,6 +17,7 @@ pub async fn rotate_keys(client: &Client) -> Result<SessionKeys, anyhow::Error>
 		.map_err(|e| anyhow!("Session keys have wrong length: {:?}", e))
 }
 
+/// set session keys
 pub async fn set_session_keys(
 	pair: Pair,
 	client: &Client,
@@ -33,12 +35,17 @@ pub async fn set_session_keys(
 		.await
 }
 
-pub async fn update_session_keys(pair: Pair, client: &Client) -> Result<TxProgress, GcliError> {
+/// update session keys
+pub async fn update_session_keys(pair: Pair, client: &Client) -> Result<(), GcliError> {
 	let session_keys = rotate_keys(client).await?;
-	set_session_keys(pair, client, session_keys).await.map_err(|e| e.into())
+	let progress = set_session_keys(pair, client, session_keys).await?;
+
+	let _ = track_progress(progress).await?; // TODO
+	Ok(())
 }
 
-pub async fn go_online(pair: Pair, client: &Client) -> Result<TxProgress, GcliError> {
+/// submit go_online
+pub async fn go_online(pair: Pair, client: &Client) -> Result<(), GcliError> {
 	if client
 		.storage()
 		.fetch(
@@ -50,30 +57,46 @@ pub async fn go_online(pair: Pair, client: &Client) -> Result<TxProgress, GcliEr
 		.await?
 		.is_none()
 	{
-		return Err(GcliError::Logic("This account has not set session keys!".to_string()));
+		return Err(GcliError::Logic(
+			"This account has not set session keys!".to_string(),
+		));
 	}
 
-	client
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().authority_members().go_online(),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await.map_err(|e| e.into())
+		.await?;
+
+	let events = track_progress(progress).await?;
+	if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOnline>()? {
+		println!("{e:?}");
+	}
+	Ok(())
 }
 
-pub async fn go_offline(pair: Pair, client: &Client) -> Result<TxProgress, subxt::Error> {
-	client
+/// submit go_offline
+pub async fn go_offline(pair: Pair, client: &Client) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().authority_members().go_offline(),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+	let events = track_progress(progress).await?;
+	if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOffline>()? {
+		println!("{e:?}");
+	}
+
+	Ok(())
 }
 
+/// get online authorities
 pub async fn online(data: &Data) -> Result<(), anyhow::Error> {
 	let client = data.client();
 	let indexer = data.indexer.clone();
@@ -155,8 +178,13 @@ pub async fn online(data: &Data) -> Result<(), anyhow::Error> {
 }
 
 /// submit a certification and track progress
-pub async fn cert(client: &Client, pair: Pair, issuer: u32, receiver: u32) -> Result<(), anyhow::Error> {
-	let mut progress = client
+pub async fn cert(
+	client: &Client,
+	pair: Pair,
+	issuer: u32,
+	receiver: u32,
+) -> Result<(), anyhow::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().smith_cert().add_cert(issuer, receiver),
@@ -165,23 +193,8 @@ pub async fn cert(client: &Client, pair: Pair, issuer: u32, receiver: u32) -> Re
 		)
 		.await?;
 
-	let in_block = 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,
-			}
-		}
-	};
-
-	// get the block events and return if ExtrinsicFailed
-	let events = in_block.wait_for_success().await?;
+	let events = track_progress(progress).await?;
+
 	// look for the expected event
 	let new_cert_event = events.find_first::<runtime::smith_cert::events::NewCert>()?;
 	let renew_cert_event = events.find_first::<runtime::smith_cert::events::RenewedCert>()?;
diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs
index 0a9b9a28e662e65614b15436c9943e06cff5da70..a0c2d9a81804c9b2fd1b0be67352a0882d669bdf 100644
--- a/src/commands/sudo.rs
+++ b/src/commands/sudo.rs
@@ -7,13 +7,16 @@ pub async fn set_key(
 	pair: Pair,
 	client: &Client,
 	new_key: AccountId32,
-) -> Result<TxProgress, subxt::Error> {
-	client
+) -> Result<(), subxt::Error> {
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().sudo().set_key(new_key.into()),
 			&PairSigner::new(pair),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let _ = track_progress(progress).await?; // TODO
+	Ok(())
 }
diff --git a/src/commands/transfer.rs b/src/commands/transfer.rs
index 6656175289e85ef8cb834ac2fdd3d0a14f1236cd..c0ebc081276debf7d95bd5ec255fefd3ff7d6931 100644
--- a/src/commands/transfer.rs
+++ b/src/commands/transfer.rs
@@ -13,8 +13,8 @@ pub async fn transfer(
 	balance: u64,
 	dest: AccountId32,
 	keep_alive: bool,
-) -> Result<TxProgress, subxt::Error> {
-	if keep_alive {
+) -> Result<(), subxt::Error> {
+	let progress = if keep_alive {
 		client
 			.tx()
 			.sign_and_submit_then_watch(
@@ -22,7 +22,7 @@ pub async fn transfer(
 				&PairSigner::new(pair),
 				BaseExtrinsicParamsBuilder::new(),
 			)
-			.await
+			.await?
 	} else {
 		client
 			.tx()
@@ -33,8 +33,15 @@ pub async fn transfer(
 				&PairSigner::new(pair),
 				BaseExtrinsicParamsBuilder::new(),
 			)
-			.await
+			.await?
+	};
+
+	let events = track_progress(progress).await?;
+
+	if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
+		println!("{e:?}");
 	}
+	Ok(())
 }
 
 pub async fn transfer_multiple(
@@ -42,7 +49,7 @@ pub async fn transfer_multiple(
 	client: &Client,
 	amount: u64,
 	dests: Vec<AccountId32>,
-) -> Result<TxProgress, subxt::Error> {
+) -> Result<(), subxt::Error> {
 	// build the list of transactions from the destination accounts
 	let transactions: Vec<Call> = dests
 		.into_iter()
@@ -55,12 +62,19 @@ pub async fn transfer_multiple(
 		.collect();
 
 	// wrap these calls in a batch call
-	client
+	let progress = client
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().utility().batch(transactions),
 			&PairSigner::new(pair.clone()),
 			BaseExtrinsicParamsBuilder::new(),
 		)
-		.await
+		.await?;
+
+	let events = track_progress(progress).await?;
+	// TODO all transfer
+	if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
+		println!("{e:?}");
+	}
+	Ok(())
 }
diff --git a/src/main.rs b/src/main.rs
index ede8ed532105a816a5f52b18e487a0a6afeacd74..9d1687270cc7b7291d80212fe1f3a38ba3370305 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -99,16 +99,30 @@ pub struct Args {
 	network: Option<String>,
 }
 
+use subxt::blocks::ExtrinsicEvents;
+use subxt::tx::TxStatus;
+
 /// track progress of transaction on the network
 /// until it is in block with success or failure
-pub async fn track_progress(progress: TxProgress) -> anyhow::Result<()> {
-	println!("submitted transaction to network, waiting 6 seconds...");
-	// wait for in block
-	let tx = progress.wait_for_in_block().await?;
-	// print result
-	println!("{:?}", tx.wait_for_success().await?);
-	// return empty
-	Ok(())
+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
 }
 
 /// custom error type intended to provide more convenient error message to user
@@ -144,7 +158,7 @@ impl From<anyhow::Error> for GcliError {
 
 #[derive(Clone, Debug, clap::Subcommand, Default)]
 pub enum Subcommand {
-	/// Fetch account balance
+	/// Fetch account balance TODO also oneshot account
 	#[default]
 	GetBalance,
 	/// Show address corresponding to given arguments
@@ -296,15 +310,11 @@ async fn main() -> Result<(), GcliError> {
 		}
 		Subcommand::CreateIdentity { target } => {
 			data = data.build_client().await?.build_keypair();
-			let progress =
-				commands::identity::create_identity(data.keypair(), data.client(), target).await?;
-			track_progress(progress).await?
+			commands::identity::create_identity(data.keypair(), data.client(), target).await?;
 		}
 		Subcommand::ConfirmIdentity { name } => {
 			data = data.build_client().await?.build_keypair();
-			let progress =
-				commands::identity::confirm_identity(data.keypair(), data.client(), name).await?;
-			track_progress(progress).await?
+			commands::identity::confirm_identity(data.keypair(), data.client(), name).await?;
 		}
 		Subcommand::RevokeIdentity => {
 			data = data
@@ -313,12 +323,11 @@ async fn main() -> Result<(), GcliError> {
 				.build_keypair()
 				.fetch_idty_index()
 				.await?;
-			let progress = commands::identity::revoke_identity(data).await?;
-			track_progress(progress).await?
+			commands::identity::revoke_identity(data).await?;
 		}
 		Subcommand::CreateOneshot { balance, dest } => {
 			data = data.build_client().await?;
-			let progress = commands::oneshot::create_oneshot_account(
+			commands::oneshot::create_oneshot_account(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -332,11 +341,10 @@ async fn main() -> Result<(), GcliError> {
 				dest,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::ConsumeOneshot { dest, dest_oneshot } => {
 			data = data.build_client().await?;
-			let progress = commands::oneshot::consume_oneshot_account(
+			commands::oneshot::consume_oneshot_account(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -350,7 +358,6 @@ async fn main() -> Result<(), GcliError> {
 				dest_oneshot,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::ConsumeOneshotWithRemaining {
 			balance,
@@ -360,7 +367,7 @@ async fn main() -> Result<(), GcliError> {
 			remaining_to_oneshot,
 		} => {
 			data = data.build_client().await?;
-			let progress = commands::oneshot::consume_oneshot_account_with_remaining(
+			commands::oneshot::consume_oneshot_account_with_remaining(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -377,7 +384,6 @@ async fn main() -> Result<(), GcliError> {
 				remaining_to_oneshot,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::Expire { blocks, sessions } => {
 			data = data.build_client().await?;
@@ -408,7 +414,7 @@ async fn main() -> Result<(), GcliError> {
 		}
 		Subcommand::GoOffline => {
 			data = data.build_client().await?;
-			let progress = commands::smith::go_offline(
+			commands::smith::go_offline(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -420,11 +426,10 @@ async fn main() -> Result<(), GcliError> {
 				data.client(),
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::GoOnline => {
 			data = data.build_client().await?;
-			let progress = commands::smith::go_online(
+			commands::smith::go_online(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -436,7 +441,6 @@ async fn main() -> Result<(), GcliError> {
 				data.client(),
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::OneshotBalance { account } => {
 			data = data.build_client().await?;
@@ -484,8 +488,7 @@ async fn main() -> Result<(), GcliError> {
 		}
 		Subcommand::SudoSetKey { new_key } => {
 			data = data.build_keypair().build_client().await?;
-			let progress = commands::sudo::set_key(data.keypair(), data.client(), new_key).await?;
-			track_progress(progress).await?;
+			commands::sudo::set_key(data.keypair(), data.client(), new_key).await?;
 		}
 		Subcommand::SmithCert { to } => {
 			data = data
@@ -511,7 +514,7 @@ async fn main() -> Result<(), GcliError> {
 				1 => true,
 				_ => panic!("Vote must be written 0 if you disagree, or 1 if you agree."),
 			};
-			let progress = commands::collective::technical_committee_vote(
+			commands::collective::technical_committee_vote(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -526,7 +529,6 @@ async fn main() -> Result<(), GcliError> {
 				vote,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::Transfer {
 			amount,
@@ -534,7 +536,7 @@ async fn main() -> Result<(), GcliError> {
 			keep_alive,
 		} => {
 			data = data.build_client().await?;
-			let progress = commands::transfer::transfer(
+			commands::transfer::transfer(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -549,11 +551,10 @@ async fn main() -> Result<(), GcliError> {
 				keep_alive,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::TransferMultiple { amount, dests } => {
 			data = data.build_client().await?;
-			let progress = commands::transfer::transfer_multiple(
+			commands::transfer::transfer_multiple(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -567,11 +568,10 @@ async fn main() -> Result<(), GcliError> {
 				dests,
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::UpdateKeys => {
 			data = data.build_client().await?;
-			let progress = commands::smith::update_session_keys(
+			commands::smith::update_session_keys(
 				get_keys(
 					args.secret_format,
 					&args.address,
@@ -583,7 +583,6 @@ async fn main() -> Result<(), GcliError> {
 				data.client(),
 			)
 			.await?;
-			track_progress(progress).await?;
 		}
 		Subcommand::RuntimeInfo => {
 			data = data.build_client().await?.fetch_system_properties().await?;