Skip to content
Snippets Groups Projects
Commit 40c8d5f2 authored by Hugo Trentesaux's avatar Hugo Trentesaux
Browse files

add smith and membership commands

parent 020be31e
No related branches found
No related tags found
No related merge requests found
{
"rust-analyzer.server.extraEnv": null,
"windicss.includeLanguages": {}
}
\ No newline at end of file
This diff is collapsed.
...@@ -15,7 +15,8 @@ gcli config where ...@@ -15,7 +15,8 @@ gcli config where
gcli --network gdev config save gcli --network gdev config save
# save config to use Alice predefined secret # save config to use Alice predefined secret
gcli -S predefined -s Alice config save 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 gcli --network local -S predefined -s test1 config save
``` ```
...@@ -23,6 +24,8 @@ In the following, we assume this last command was run. ...@@ -23,6 +24,8 @@ In the following, we assume this last command was run.
## Commands ## Commands
Here is a list of useful commands
```sh ```sh
# get duniter current block # get duniter current block
gcli blockchain current-block gcli blockchain current-block
...@@ -38,6 +41,15 @@ gcli ud claim ...@@ -38,6 +41,15 @@ gcli ud claim
gcli account transfer 5000 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb gcli account transfer 5000 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb
``` ```
For testing purpose it can be useful to submit extrinsic without waiting for result and create block manually.
```sh
# only submit extrinsic to network and do not listen to result
gcli --no-wait account transfer 1234 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa
# create block manually (with manual sealing)
gcli blockchain create-block
```
## Indexer commands ## Indexer commands
You can check first that indexer is on the same network as Duniter node: You can check first that indexer is on the same network as Duniter node:
......
No preview for this file type
[toolchain]
channel = "nightly"
pub mod account; pub mod account;
pub mod blockchain; pub mod blockchain;
pub mod certification;
pub mod collective; pub mod collective;
pub mod expire; pub mod expire;
pub mod identity; pub mod identity;
......
...@@ -32,7 +32,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -32,7 +32,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
match command { match command {
Subcommand::Balance => { Subcommand::Balance => {
data = data.fetch_system_properties().await?; data = data.fetch_system_properties().await?;
commands::account::get_balance(data).await? get_balance(data).await?
} }
Subcommand::Transfer { Subcommand::Transfer {
amount, amount,
......
...@@ -18,6 +18,9 @@ pub enum Subcommand { ...@@ -18,6 +18,9 @@ pub enum Subcommand {
/// Check current block /// Check current block
#[default] #[default]
CurrentBlock, CurrentBlock,
/// Create one block manually (manual sealing)
#[clap(hide = true)]
CreateBlock,
} }
/// handle blockchain commands /// handle blockchain commands
...@@ -46,6 +49,12 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -46,6 +49,12 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
.unwrap() .unwrap()
); );
} }
Subcommand::CreateBlock => {
data.client()
.rpc()
.request("engine_createBlock", subxt::rpc::rpc_params![true, true]) // create empty block and finalize
.await?; // FIXME this gives a serialization error
}
} }
Ok(()) Ok(())
} }
......
use crate::*;
/// submit a certification and track progress
pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
let progress = data
.client()
.tx()
.sign_and_submit_then_watch(
&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
let new_cert_event = events.find_first::<runtime::cert::events::NewCert>()?;
let renew_cert_event = events.find_first::<runtime::cert::events::RenewedCert>()?;
if let Some(event) = new_cert_event {
println!("{event:?}");
}
if let Some(event) = renew_cert_event {
println!("{event:?}");
}
Ok(())
}
...@@ -147,6 +147,9 @@ pub async fn technical_committee_vote( ...@@ -147,6 +147,9 @@ pub async fn technical_committee_vote(
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::technical_committee::events::Voted>()? { if let Some(e) = events.find_first::<runtime::technical_committee::events::Voted>()? {
......
use crate::*; use crate::*;
use crate::commands::revocation::generate_revoc_doc; use crate::{
use crate::runtime::runtime_types::common_runtime::entities::IdtyData; commands::revocation::generate_revoc_doc,
use crate::runtime::runtime_types::pallet_identity::types::*; runtime::runtime_types::{
use crate::runtime::runtime_types::sp_core::sr25519::Signature; common_runtime::entities::IdtyData, pallet_identity::types::*, sp_core::sr25519::Signature,
use crate::runtime::runtime_types::sp_runtime::MultiSignature; sp_runtime::MultiSignature,
},
};
use std::str::FromStr; use std::str::FromStr;
/// define identity subcommands /// define identity subcommands
...@@ -30,10 +32,14 @@ pub enum Subcommand { ...@@ -30,10 +32,14 @@ pub enum Subcommand {
/// ///
/// To be called by the certified not-yet-member account, to become member. /// To be called by the certified not-yet-member account, to become member.
Confirm { name: String }, Confirm { name: String },
/// Certify an identity
Certify { target: u32 },
/// Revoke an identity immediately /// Revoke an identity immediately
Revoke, Revoke,
/// Generate a revocation document for the provided account /// Generate a revocation document for the provided account
GenRevocDoc, GenRevocDoc,
/// Display member count
MemberCount,
} }
/// handle identity commands /// handle identity commands
...@@ -47,28 +53,41 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -47,28 +53,41 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
ref username, ref username,
} => { } => {
data = data.build_indexer().await?; data = data.build_indexer().await?;
commands::identity::get_identity( get_identity(&data, account_id.clone(), identity_id, username.clone()).await?
&data,
account_id.clone(),
identity_id,
username.clone(),
)
.await?
} }
Subcommand::Create { target } => { Subcommand::Create { target } => {
commands::identity::create_identity(data.keypair(), data.client(), target).await?; create_identity(&data, target).await?;
} }
Subcommand::Confirm { name } => { Subcommand::Confirm { name } => {
commands::identity::confirm_identity(data.keypair(), data.client(), name).await?; confirm_identity(&data, name).await?;
}
Subcommand::Certify { target } => {
data = data.fetch_idty_index().await?;
// TODO fetch target username / key / index
// and ask user to confirm certification
commands::certification::certify(&data, target).await?;
} }
Subcommand::Revoke => { Subcommand::Revoke => {
data = data.fetch_idty_index().await?; data = data.fetch_idty_index().await?;
commands::identity::revoke_identity(data).await?; revoke_identity(data).await?;
} }
Subcommand::GenRevocDoc => { Subcommand::GenRevocDoc => {
data = data.fetch_idty_index().await?; data = data.fetch_idty_index().await?;
commands::revocation::print_revoc_sig(&data) commands::revocation::print_revoc_sig(&data)
} }
Subcommand::MemberCount => {
println!(
"member count: {}",
data.client()
.storage()
.fetch(
&runtime::storage().membership().counter_for_membership(),
None,
)
.await?
.unwrap()
)
}
}; };
Ok(()) Ok(())
...@@ -166,20 +185,20 @@ pub async fn get_identity_by_index( ...@@ -166,20 +185,20 @@ pub async fn get_identity_by_index(
} }
/// created identity /// created identity
pub async fn create_identity( pub async fn create_identity(data: &Data, target: AccountId) -> Result<(), subxt::Error> {
pair: Pair, let progress = data
client: &Client, .client()
target: AccountId,
) -> Result<(), subxt::Error> {
let progress = client
.tx() .tx()
.sign_and_submit_then_watch( .sign_and_submit_then_watch(
&runtime::tx().identity().create_identity(target), &runtime::tx().identity().create_identity(target),
&PairSigner::new(pair), &PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(), BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::identity::events::IdtyCreated>()? { if let Some(e) = events.find_first::<runtime::identity::events::IdtyCreated>()? {
println!("{e:?}"); println!("{e:?}");
...@@ -188,20 +207,20 @@ pub async fn create_identity( ...@@ -188,20 +207,20 @@ pub async fn create_identity(
} }
/// confirm identity /// confirm identity
pub async fn confirm_identity( pub async fn confirm_identity(data: &Data, name: String) -> Result<(), subxt::Error> {
pair: Pair, let progress = data
client: &Client, .client()
name: String,
) -> Result<(), subxt::Error> {
let progress = client
.tx() .tx()
.sign_and_submit_then_watch( .sign_and_submit_then_watch(
&runtime::tx().identity().confirm_identity(name), &runtime::tx().identity().confirm_identity(name),
&PairSigner::new(pair), &PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(), BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::identity::events::IdtyConfirmed>()? { if let Some(e) = events.find_first::<runtime::identity::events::IdtyConfirmed>()? {
println!("{e:?}"); println!("{e:?}");
...@@ -230,6 +249,9 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> { ...@@ -230,6 +249,9 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> {
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::identity::events::IdtyRemoved>()? { if let Some(e) = events.find_first::<runtime::identity::events::IdtyRemoved>()? {
println!("{e:?}"); println!("{e:?}");
......
...@@ -102,6 +102,9 @@ pub async fn create_oneshot_account( ...@@ -102,6 +102,9 @@ pub async fn create_oneshot_account(
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = if let Some(e) =
events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()? events.find_first::<runtime::oneshot_account::events::OneshotAccountCreated>()?
...@@ -145,6 +148,9 @@ pub async fn consume_oneshot_account( ...@@ -145,6 +148,9 @@ pub async fn consume_oneshot_account(
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = if let Some(e) =
events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()? events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
...@@ -157,7 +163,6 @@ pub async fn consume_oneshot_account( ...@@ -157,7 +163,6 @@ pub async fn consume_oneshot_account(
/// consume oneshot account with remaining /// consume oneshot account with remaining
pub async fn consume_oneshot_account_with_remaining( pub async fn consume_oneshot_account_with_remaining(
data: &Data, data: &Data,
balance: u64, balance: u64,
dest: AccountId, dest: AccountId,
dest_oneshot: bool, dest_oneshot: bool,
...@@ -203,6 +208,9 @@ pub async fn consume_oneshot_account_with_remaining( ...@@ -203,6 +208,9 @@ pub async fn consume_oneshot_account_with_remaining(
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = if let Some(e) =
events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()? events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
......
...@@ -14,6 +14,10 @@ pub enum Subcommand { ...@@ -14,6 +14,10 @@ pub enum Subcommand {
Request { endpoint: String }, Request { endpoint: String },
/// Emit a smith certification /// Emit a smith certification
Cert { to: u32 }, Cert { to: u32 },
/// Claim smith membership
Claim,
/// Renew smith membership
Renew,
/// go online /// go online
GoOnline, GoOnline,
/// go offline /// go offline
...@@ -34,6 +38,8 @@ pub enum Subcommand { ...@@ -34,6 +38,8 @@ pub enum Subcommand {
}, },
/// List online authorities /// List online authorities
ShowOnline, ShowOnline,
/// count of smith member
MemberCount,
} }
/// handle smith commands /// handle smith commands
...@@ -41,7 +47,13 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -41,7 +47,13 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
let mut data = data.build_client().await?; let mut data = data.build_client().await?;
match command { match command {
Subcommand::Request { endpoint } => { Subcommand::Request { endpoint } => {
dbg!(request_smith_membership(&data, endpoint).await)?; request_smith_membership(&data, endpoint).await?;
}
Subcommand::Claim => {
claim_smith_membership(&data).await?;
}
Subcommand::Renew => {
renew_smith_membership(&data).await?;
} }
Subcommand::GoOnline => { Subcommand::GoOnline => {
go_online(&data).await?; go_online(&data).await?;
...@@ -58,7 +70,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -58,7 +70,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
} }
Subcommand::SudoSetKey { new_key } => { Subcommand::SudoSetKey { new_key } => {
data = data.build_client().await?; 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 } => { Subcommand::ShowExpire { blocks, sessions } => {
data = data.build_client().await?.build_indexer().await?; data = data.build_client().await?.build_indexer().await?;
...@@ -68,6 +80,18 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -68,6 +80,18 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
data = data.build_client().await?; data = data.build_client().await?;
online(&data).await? online(&data).await?
} }
Subcommand::MemberCount => {
println!(
"smith member count: {:?}",
data.client()
.storage()
.fetch(
&runtime::storage().smith_membership().counter_for_membership(),
None,
)
.await?
)
}
}; };
Ok(()) Ok(())
...@@ -104,6 +128,10 @@ pub async fn request_smith_membership(data: &Data, endpoint: String) -> Result<( ...@@ -104,6 +128,10 @@ pub async fn request_smith_membership(data: &Data, endpoint: String) -> Result<(
BaseExtrinsicParamsBuilder::new(), BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
let request = events.find_first::<runtime::smith_membership::events::MembershipRequested>()?; let request = events.find_first::<runtime::smith_membership::events::MembershipRequested>()?;
if let Some(event) = request { if let Some(event) = request {
...@@ -134,6 +162,9 @@ pub async fn update_session_keys(data: &Data) -> Result<(), GcliError> { ...@@ -134,6 +162,9 @@ pub async fn update_session_keys(data: &Data) -> Result<(), GcliError> {
let session_keys = rotate_keys(data.client()).await?; let session_keys = rotate_keys(data.client()).await?;
let progress = set_session_keys(data, session_keys).await?; let progress = set_session_keys(data, session_keys).await?;
if data.args.no_wait {
return Ok(());
}
let _ = track_progress(progress).await?; // TODO let _ = track_progress(progress).await?; // TODO
Ok(()) Ok(())
} }
...@@ -155,40 +186,38 @@ pub async fn go_online(data: &Data) -> Result<(), GcliError> { ...@@ -155,40 +186,38 @@ pub async fn go_online(data: &Data) -> Result<(), GcliError> {
)); ));
} }
let progress = data submit_call_and_look_event::<
.client() runtime::authority_members::events::MemberGoOnline,
.tx() StaticTxPayload<runtime::authority_members::calls::GoOnline>,
.sign_and_submit_then_watch( >(data, &runtime::tx().authority_members().go_online())
&runtime::tx().authority_members().go_online(), .await.map_err(|e| e.into())
&PairSigner::new(data.keypair()), }
BaseExtrinsicParamsBuilder::new(),
)
.await?;
let events = track_progress(progress).await?; /// claim smith membership
if let Some(e) = events.find_first::<runtime::authority_members::events::MemberGoOnline>()? { pub async fn claim_smith_membership(data: &Data) -> Result<(), subxt::Error> {
println!("{e:?}"); submit_call_and_look_event::<
} runtime::smith_membership::events::MembershipAcquired,
Ok(()) StaticTxPayload<runtime::smith_membership::calls::ClaimMembership>,
>(data, &runtime::tx().smith_membership().claim_membership())
.await
}
/// renew smith membership
pub async fn renew_smith_membership(data: &Data) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::smith_membership::events::MembershipRenewed,
StaticTxPayload<runtime::smith_membership::calls::RenewMembership>,
>(data, &runtime::tx().smith_membership().renew_membership())
.await
} }
/// submit go_offline /// submit go_offline
pub async fn go_offline(data: &Data) -> Result<(), subxt::Error> { pub async fn go_offline(data: &Data) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::authority_members::events::MemberGoOffline,
.tx() StaticTxPayload<runtime::authority_members::calls::GoOffline>,
.sign_and_submit_then_watch( >(data, &runtime::tx().authority_members().go_offline())
&runtime::tx().authority_members().go_offline(), .await
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.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 /// get online authorities
...@@ -286,6 +315,9 @@ pub async fn cert(data: &Data, receiver: u32) -> Result<(), anyhow::Error> { ...@@ -286,6 +315,9 @@ pub async fn cert(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
// look for the expected event // look for the expected event
......
use crate::*; use crate::*;
/// set sudo key /// set sudo key
pub async fn set_key(pair: Pair, client: &Client, new_key: AccountId) -> Result<(), subxt::Error> { pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> {
let progress = client let progress = data
.client()
.tx() .tx()
.sign_and_submit_then_watch( .sign_and_submit_then_watch(
&runtime::tx().sudo().set_key(new_key.into()), &runtime::tx().sudo().set_key(new_key.into()),
&PairSigner::new(pair), &PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(), BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let _ = track_progress(progress).await?; // TODO let _ = track_progress(progress).await?; // TODO
Ok(()) Ok(())
} }
...@@ -33,6 +33,9 @@ pub async fn transfer( ...@@ -33,6 +33,9 @@ pub async fn transfer(
.await? .await?
}; };
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? { if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
...@@ -69,6 +72,9 @@ pub async fn transfer_multiple( ...@@ -69,6 +72,9 @@ pub async fn transfer_multiple(
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
// TODO all transfer // TODO all transfer
if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? { if let Some(e) = events.find_first::<runtime::balances::events::Transfer>()? {
......
...@@ -34,6 +34,9 @@ pub async fn claim_ud(data: Data) -> Result<(), anyhow::Error> { ...@@ -34,6 +34,9 @@ pub async fn claim_ud(data: Data) -> Result<(), anyhow::Error> {
) )
.await?; .await?;
if data.args.no_wait {
return Ok(());
}
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
if let Some(e) = events.find_first::<runtime::universal_dividend::events::UdsClaimed>()? { if let Some(e) = events.find_first::<runtime::universal_dividend::events::UdsClaimed>()? {
......
...@@ -157,8 +157,10 @@ impl Data { ...@@ -157,8 +157,10 @@ impl Data {
let derivation = match &derivation[..] { let derivation = match &derivation[..] {
"test1" => "2", "test1" => "2",
"test2" => "4", "test2" => "4",
"test3" => "3", "test3" => "6",
_ => "" "test4" => "8",
"test5" => "10",
_ => "",
}; };
self.cfg.secret = Some(format!("{TEST_MNEMONIC}//{derivation}")); self.cfg.secret = Some(format!("{TEST_MNEMONIC}//{derivation}"));
} else { } else {
...@@ -173,21 +175,17 @@ impl Data { ...@@ -173,21 +175,17 @@ impl Data {
// address // address
if let Some(address) = self.args.address.clone() { if let Some(address) = self.args.address.clone() {
self.cfg.address = Some(AccountId::from_str(&address).expect("invalid address")); self.cfg.address = Some(AccountId::from_str(&address).expect("invalid address"));
// if giving address, cancel secret
self.cfg.secret = None
} }
self self
} }
/// build from config /// build from config
pub fn build_from_config(mut self) -> Self { 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() { if let Some(secret) = self.cfg.secret.clone() {
let (address, keypair) = let (address, keypair) =
addr_and_pair_from_secret(SecretFormat::Predefined, &secret).unwrap(); 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.address = Some(address);
self.cfg.secret = Some(secret); self.cfg.secret = Some(secret);
self.keypair = Some(keypair); self.keypair = Some(keypair);
......
...@@ -16,7 +16,8 @@ use runtime_config::*; ...@@ -16,7 +16,8 @@ use runtime_config::*;
use serde::Deserialize; use serde::Deserialize;
use sp_core::{sr25519::Pair, Pair as _}; use sp_core::{sr25519::Pair, Pair as _};
use subxt::blocks::ExtrinsicEvents; use subxt::blocks::ExtrinsicEvents;
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner, TxStatus}; use subxt::events::StaticEvent;
use subxt::tx::{BaseExtrinsicParamsBuilder, PairSigner, TxPayload, TxStatus, StaticTxPayload};
use utils::*; use utils::*;
/// define command line arguments /// define command line arguments
...@@ -48,6 +49,9 @@ pub struct Args { ...@@ -48,6 +49,9 @@ pub struct Args {
/// Target network (local, gdev, gtest...) /// Target network (local, gdev, gtest...)
#[clap(short, long)] #[clap(short, long)]
network: Option<String>, network: Option<String>,
/// prevent waiting for extrinsic completion
#[clap(long)]
no_wait: bool,
} }
/// define subcommands /// define subcommands
...@@ -97,7 +101,7 @@ async fn main() -> Result<(), GcliError> { ...@@ -97,7 +101,7 @@ async fn main() -> Result<(), GcliError> {
// match subcommands // match subcommands
match data.args.subcommand.clone() { match data.args.subcommand.clone() {
Subcommand::DoNothing => {Ok(())} Subcommand::DoNothing => Ok(()),
Subcommand::Account(subcommand) => { Subcommand::Account(subcommand) => {
commands::account::handle_command(data, subcommand).await commands::account::handle_command(data, subcommand).await
} }
...@@ -117,5 +121,6 @@ async fn main() -> Result<(), GcliError> { ...@@ -117,5 +121,6 @@ async fn main() -> Result<(), GcliError> {
} }
Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await, Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await,
Subcommand::Config(subcommand) => conf::handle_command(data, subcommand), Subcommand::Config(subcommand) => conf::handle_command(data, subcommand),
}.map_err(|e| dbg!(e).into()) }
.map_err(|e| dbg!(e).into())
} }
...@@ -23,6 +23,32 @@ pub async fn track_progress( ...@@ -23,6 +23,32 @@ pub async fn track_progress(
.await .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 /// custom error type intended to provide more convenient error message to user
#[derive(Debug)] #[derive(Debug)]
pub enum GcliError { pub enum GcliError {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment