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()) }