diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..37912cf0f3eec7e189ad2b08d64e5f828798f439
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+    "rust-analyzer.server.extraEnv": null,
+    "windicss.includeLanguages": {}
+}
\ No newline at end of file
diff --git a/doc/example.md b/doc/example.md
index b53a28727ec2052413a42b2d4bb1b407e451c49b..0a6f9f8f9e817253a63d7c76696f7fcc0cb58b90 100644
--- a/doc/example.md
+++ b/doc/example.md
@@ -15,7 +15,8 @@ gcli config where
 gcli --network gdev config save
 # save config to use Alice predefined secret
 gcli -S predefined -s Alice config save
-# these can be combined
+# the arguments above can be combined
+# command below sets local network and predefined secret
 gcli --network local -S predefined -s test1 config save
 ```
 
@@ -23,6 +24,8 @@ In the following, we assume this last command was run.
 
 ## Commands
 
+Here is a list of useful commands
+
 ```sh
 # get duniter current block
 gcli blockchain current-block
@@ -38,6 +41,13 @@ gcli ud claim
 gcli account transfer 5000 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb
 ```
 
+If you want to submit extrinsics without tracking progress:
+
+```sh
+# only submit extrinsic to network and do not listen to result
+gcli --no-wait account transfer 1234 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa
+```
+
 ## Indexer commands
 
 You can check first that indexer is on the same network as Duniter node:
diff --git a/src/commands/certification.rs b/src/commands/certification.rs
index 0651cc684949f06700f01e0e3a2f9a129f5e0f9e..69a2f11eb4f81d2e21471497d0e3ae47b2b3a17b 100644
--- a/src/commands/certification.rs
+++ b/src/commands/certification.rs
@@ -6,14 +6,15 @@ pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
 		.client()
 		.tx()
 		.sign_and_submit_then_watch(
-			&runtime::tx()
-				.cert()
-				.add_cert(data.idty_index(), receiver),
+			&runtime::tx().cert().add_cert(data.idty_index(), receiver),
 			&PairSigner::new(data.keypair()),
 			BaseExtrinsicParamsBuilder::new(),
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 
 	// look for the expected event
diff --git a/src/commands/collective.rs b/src/commands/collective.rs
index 92c8da45bc325ed598201bf1865ceb1f3a79b5b2..5ca295e7958ec04e772c54edf256bd6d8081e6a9 100644
--- a/src/commands/collective.rs
+++ b/src/commands/collective.rs
@@ -147,6 +147,9 @@ pub async fn technical_committee_vote(
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 
 	if let Some(e) = events.find_first::<runtime::technical_committee::events::Voted>()? {
diff --git a/src/commands/identity.rs b/src/commands/identity.rs
index 9c7c1fb92c093c680ee9ffe52d3e51d41f432562..f073c694ad25c334fd48eca8b7d1b88d944e7461 100644
--- a/src/commands/identity.rs
+++ b/src/commands/identity.rs
@@ -58,10 +58,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
 			.await?
 		}
 		Subcommand::Create { target } => {
-			commands::identity::create_identity(data.keypair(), data.client(), target).await?;
+			commands::identity::create_identity(&data, target).await?;
 		}
 		Subcommand::Confirm { name } => {
-			commands::identity::confirm_identity(data.keypair(), data.client(), name).await?;
+			commands::identity::confirm_identity(&data, name).await?;
 		}
 		Subcommand::Certify { target } => {
 			data = data.fetch_idty_index().await?;
@@ -174,20 +174,20 @@ pub async fn get_identity_by_index(
 }
 
 /// created identity
-pub async fn create_identity(
-	pair: Pair,
-	client: &Client,
-	target: AccountId,
-) -> Result<(), subxt::Error> {
-	let progress = client
+pub async fn create_identity(data: &Data, target: AccountId) -> Result<(), subxt::Error> {
+	let progress = data
+		.client()
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().create_identity(target),
-			&PairSigner::new(pair),
+			&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::<runtime::identity::events::IdtyCreated>()? {
 		println!("{e:?}");
@@ -196,20 +196,20 @@ pub async fn create_identity(
 }
 
 /// confirm identity
-pub async fn confirm_identity(
-	pair: Pair,
-	client: &Client,
-	name: String,
-) -> Result<(), subxt::Error> {
-	let progress = client
+pub async fn confirm_identity(data: &Data, name: String) -> Result<(), subxt::Error> {
+	let progress = data
+		.client()
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().identity().confirm_identity(name),
-			&PairSigner::new(pair),
+			&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::<runtime::identity::events::IdtyConfirmed>()? {
 		println!("{e:?}");
@@ -238,6 +238,9 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> {
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) = events.find_first::<runtime::identity::events::IdtyRemoved>()? {
 		println!("{e:?}");
diff --git a/src/commands/oneshot.rs b/src/commands/oneshot.rs
index 6c8b9c1b9bef214ca8d6d62aa1b6568567e3f345..a395f78bd3a006f810f5e607e323ec2948cc1c58 100644
--- a/src/commands/oneshot.rs
+++ b/src/commands/oneshot.rs
@@ -102,6 +102,9 @@ pub async fn create_oneshot_account(
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) =
 		events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()?
@@ -145,6 +148,9 @@ pub async fn consume_oneshot_account(
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) =
 		events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
@@ -157,7 +163,6 @@ pub async fn consume_oneshot_account(
 /// consume oneshot account with remaining
 pub async fn consume_oneshot_account_with_remaining(
 	data: &Data,
-
 	balance: u64,
 	dest: AccountId,
 	dest_oneshot: bool,
@@ -203,6 +208,9 @@ pub async fn consume_oneshot_account_with_remaining(
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) =
 		events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
diff --git a/src/commands/smith.rs b/src/commands/smith.rs
index 96092c4d60fdbffdaefc9eab6a7cd859cd07d11c..bc60a5d18f2e25d395c6f626427a3498cdc52ef3 100644
--- a/src/commands/smith.rs
+++ b/src/commands/smith.rs
@@ -58,7 +58,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
 		}
 		Subcommand::SudoSetKey { new_key } => {
 			data = data.build_client().await?;
-			commands::sudo::set_key(data.keypair(), data.client(), new_key).await?;
+			commands::sudo::set_key(&data, new_key).await?;
 		}
 		Subcommand::ShowExpire { blocks, sessions } => {
 			data = data.build_client().await?.build_indexer().await?;
@@ -104,6 +104,10 @@ pub async fn request_smith_membership(data: &Data, endpoint: String) -> Result<(
 			BaseExtrinsicParamsBuilder::new(),
 		)
 		.await?;
+
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	let request = events.find_first::<runtime::smith_membership::events::MembershipRequested>()?;
 	if let Some(event) = request {
@@ -134,6 +138,9 @@ pub async fn update_session_keys(data: &Data) -> Result<(), GcliError> {
 	let session_keys = rotate_keys(data.client()).await?;
 	let progress = set_session_keys(data, session_keys).await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let _ = track_progress(progress).await?; // TODO
 	Ok(())
 }
@@ -165,6 +172,9 @@ pub async fn go_online(data: &Data) -> Result<(), GcliError> {
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOnline>()? {
 		println!("{e:?}");
@@ -183,6 +193,10 @@ pub async fn go_offline(data: &Data) -> Result<(), subxt::Error> {
 			BaseExtrinsicParamsBuilder::new(),
 		)
 		.await?;
+
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOffline>()? {
 		println!("{e:?}");
@@ -286,6 +300,9 @@ pub async fn cert(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 
 	// look for the expected event
diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs
index 7182fdfd1f1df13b05016400f985f8cd797a353a..9e5d56cf5ea18e3a38d641889ff4b372ce058116 100644
--- a/src/commands/sudo.rs
+++ b/src/commands/sudo.rs
@@ -1,16 +1,20 @@
 use crate::*;
 
 /// set sudo key
-pub async fn set_key(pair: Pair, client: &Client, new_key: AccountId) -> Result<(), subxt::Error> {
-	let progress = client
+pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> {
+	let progress = data
+		.client()
 		.tx()
 		.sign_and_submit_then_watch(
 			&runtime::tx().sudo().set_key(new_key.into()),
-			&PairSigner::new(pair),
+			&PairSigner::new(data.keypair()),
 			BaseExtrinsicParamsBuilder::new(),
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let _ = track_progress(progress).await?; // TODO
 	Ok(())
 }
diff --git a/src/commands/transfer.rs b/src/commands/transfer.rs
index ca6ab53aa1f9ac22c452677c144d9773a0f9b606..547797d50072d5d8ff82cea883e20a2fb3d6655f 100644
--- a/src/commands/transfer.rs
+++ b/src/commands/transfer.rs
@@ -33,6 +33,9 @@ pub async fn transfer(
 			.await?
 	};
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 
 	if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
@@ -69,6 +72,9 @@ pub async fn transfer_multiple(
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 	// TODO all transfer
 	if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
diff --git a/src/commands/ud.rs b/src/commands/ud.rs
index 1a7d143023a2f45a75fb550da8a2e50a96bb3bdd..bda66f03909c87cde64ae697a7da193ff74432c4 100644
--- a/src/commands/ud.rs
+++ b/src/commands/ud.rs
@@ -34,6 +34,9 @@ pub async fn claim_ud(data: Data) -> Result<(), anyhow::Error> {
 		)
 		.await?;
 
+	if data.args.no_wait {
+		return Ok(());
+	}
 	let events = track_progress(progress).await?;
 
 	if let Some(e) = events.find_first::<runtime::universal_dividend::events::UdsClaimed>()? {
diff --git a/src/data.rs b/src/data.rs
index 9f378a809b3c0c4f9e58db28de9373fb0e84cff2..47e0007c3eb94967a17b4860d52b4e1182f62a35 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -160,7 +160,7 @@ impl Data {
 							"test3" => "6",
 							"test4" => "8",
 							"test5" => "10",
-							_ => ""
+							_ => "",
 						};
 						self.cfg.secret = Some(format!("{TEST_MNEMONIC}//{derivation}"));
 					} else {
@@ -175,21 +175,17 @@ impl Data {
 		// address
 		if let Some(address) = self.args.address.clone() {
 			self.cfg.address = Some(AccountId::from_str(&address).expect("invalid address"));
+			// if giving address, cancel secret
+			self.cfg.secret = None
 		}
 		self
 	}
 	/// build from config
 	pub fn build_from_config(mut self) -> Self {
-		// if a secret is defined, build keypair
+		// if a secret is defined, build keypair and silently overwrite address
 		if let Some(secret) = self.cfg.secret.clone() {
 			let (address, keypair) =
 				addr_and_pair_from_secret(SecretFormat::Predefined, &secret).unwrap();
-			// if an address is already defined and differs from secret, warns user
-			if let Some(address_) = self.cfg.address {
-				if address_ != address {
-					println!("overwriting address ({address_}) from secret ({address})");
-				}
-			}
 			self.cfg.address = Some(address);
 			self.cfg.secret = Some(secret);
 			self.keypair = Some(keypair);
diff --git a/src/main.rs b/src/main.rs
index bbf47a9256bef88d0c21e335e770e2e2f2baf56c..030de860eb7cfd67bc1dc267c18936e61b174397 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -48,6 +48,9 @@ pub struct Args {
 	/// Target network (local, gdev, gtest...)
 	#[clap(short, long)]
 	network: Option<String>,
+	/// prevent waiting for extrinsic completion
+	#[clap(long)]
+	no_wait: bool,
 }
 
 /// define subcommands
@@ -97,7 +100,7 @@ async fn main() -> Result<(), GcliError> {
 
 	// match subcommands
 	match data.args.subcommand.clone() {
-		Subcommand::DoNothing => {Ok(())}
+		Subcommand::DoNothing => Ok(()),
 		Subcommand::Account(subcommand) => {
 			commands::account::handle_command(data, subcommand).await
 		}
@@ -117,5 +120,6 @@ async fn main() -> Result<(), GcliError> {
 		}
 		Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await,
 		Subcommand::Config(subcommand) => conf::handle_command(data, subcommand),
-	}.map_err(|e| dbg!(e).into())
+	}
+	.map_err(|e| dbg!(e).into())
 }