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

refac call submission and event watch

parent bea7e02e
Branches
Tags
1 merge request!11refac call submission and event watch
...@@ -66,3 +66,11 @@ Secret and/or public keys can always be passed using `--secret` and `--address`. ...@@ -66,3 +66,11 @@ Secret and/or public keys can always be passed using `--secret` and `--address`.
Secret key format can be changed using `--secret-format` with the following values: Secret key format can be changed using `--secret-format` with the following values:
* `substrate`: a Substrate secret address (optionally followed by a derivation path), or BIP39 mnemonic * `substrate`: a Substrate secret address (optionally followed by a derivation path), or BIP39 mnemonic
* `seed`: a 32-bytes seed in hexadecimal (Duniter v1 compatible) * `seed`: a 32-bytes seed in hexadecimal (Duniter v1 compatible)
## TODO
- [x] implement config formatter
- [x] add link/unlink account commands
- [ ] migrate all xt to submit_call_and_look_event
- [ ] add transfer with unit (ĞD, UD...)
- [ ]
\ No newline at end of file
# Ğcli config
Some Ğcli commands require to have an address configured (for example to get account balance), some require to have a secret configured (to sign extrinsics).
Ğcli allows to save what you want in a config file and to overwrite parts in command line arguments. Example:
```sh
# save Alice secret to config file
cargo run -- -S predefined -s Alice config save
# show config
cargo run -- config show
# [stdout]
# Ğcli config
# duniter endpoint ws://localhost:9944
# indexer endpoint http://localhost:8080/v1/graphql
# address 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY (secret defined)
# use different address in command line
cargo run -- --address 5Fxune7f71ZbpP2FoY3mhYcmM596Erhv1gRue4nsPwkxMR4n config show
# [stdout]
# Ğcli config
# duniter endpoint ws://localhost:9944
# indexer endpoint http://localhost:8080/v1/graphql
# address 5Fxune7f71ZbpP2FoY3mhYcmM596Erhv1gRue4nsPwkxMR4n (no secret)
```
You can see that if a secret is defined, the associated address is used, but if an other address is given, the secret is silenced.
\ No newline at end of file
...@@ -20,7 +20,7 @@ gcli -S predefined -s Alice config save ...@@ -20,7 +20,7 @@ gcli -S predefined -s Alice config save
gcli --network local -S predefined -s test1 config save gcli --network local -S predefined -s test1 config save
``` ```
In the following, we assume this last command was run. In the following, we assume this last command was run. More about the config in [config.md](./config.md).
## Commands ## Commands
......
...@@ -27,6 +27,8 @@ pub enum Subcommand { ...@@ -27,6 +27,8 @@ pub enum Subcommand {
/// List of target addresses /// List of target addresses
dests: Vec<AccountId>, dests: Vec<AccountId>,
}, },
/// Unlink the account from the linked identity
Unlink,
} }
/// handle account commands /// handle account commands
...@@ -48,6 +50,9 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -48,6 +50,9 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
Subcommand::TransferMultiple { amount, dests } => { Subcommand::TransferMultiple { amount, dests } => {
commands::transfer::transfer_multiple(&data, amount, dests).await?; commands::transfer::transfer_multiple(&data, amount, dests).await?;
} }
Subcommand::Unlink => {
unlink_account(&data).await?;
}
}; };
Ok(()) Ok(())
...@@ -78,3 +83,12 @@ pub async fn get_account_info( ...@@ -78,3 +83,12 @@ pub async fn get_account_info(
.fetch(&runtime::storage().system().account(account_id), None) .fetch(&runtime::storage().system().account(account_id), None)
.await .await
} }
/// unlink account
pub async fn unlink_account(data: &Data) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::account::events::AccountUnlinked,
StaticTxPayload<runtime::account::calls::UnlinkIdentity>,
>(data, &runtime::tx().account().unlink_identity())
.await
}
...@@ -2,31 +2,17 @@ use crate::*; ...@@ -2,31 +2,17 @@ use crate::*;
/// submit a certification and track progress /// submit a certification and track progress
pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> { pub async fn certify(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
let progress = data let progress = submit_call(
.client() data,
.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?; .await?;
if data.args.no_wait { if data.args.no_wait {
return Ok(()); return Ok(());
} }
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
// look for the expected event // look for the expected event
let new_cert_event = events.find_first::<runtime::cert::events::NewCert>()?; look_event::<runtime::cert::events::NewCert>(&events)?;
let renew_cert_event = events.find_first::<runtime::cert::events::RenewedCert>()?; look_event::<runtime::cert::events::RenewedCert>(&events)?;
if let Some(event) = new_cert_event {
println!("{event:?}");
}
if let Some(event) = renew_cert_event {
println!("{event:?}");
}
Ok(()) Ok(())
} }
...@@ -135,26 +135,14 @@ pub async fn technical_committee_vote( ...@@ -135,26 +135,14 @@ pub async fn technical_committee_vote(
proposal_index: u32, proposal_index: u32,
vote: bool, vote: bool,
) -> Result<(), subxt::Error> { ) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::technical_committee::events::Voted,
.tx() StaticTxPayload<runtime::technical_committee::calls::Vote>,
.sign_and_submit_then_watch( >(
data,
&runtime::tx() &runtime::tx()
.technical_committee() .technical_committee()
.vote(proposal_hash, proposal_index, vote), .vote(proposal_hash, proposal_index, vote),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
) )
.await?; .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>()? {
println!("{e:?}");
}
Ok(())
} }
...@@ -3,7 +3,9 @@ use crate::*; ...@@ -3,7 +3,9 @@ use crate::*;
use crate::{ use crate::{
commands::revocation::generate_revoc_doc, commands::revocation::generate_revoc_doc,
runtime::runtime_types::{ runtime::runtime_types::{
common_runtime::entities::IdtyData, pallet_identity::types::*, sp_core::sr25519::Signature, common_runtime::entities::{IdtyData, NewOwnerKeySignature},
pallet_identity::types::*,
sp_core::sr25519::Signature,
sp_runtime::MultiSignature, sp_runtime::MultiSignature,
}, },
}; };
...@@ -32,6 +34,12 @@ pub enum Subcommand { ...@@ -32,6 +34,12 @@ 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 },
/// Validate an identity
/// Should be called when the distance has been evaluated positively
Validate { index: u32 },
/// Renew membership
/// When membership comes to and end, it should be renewed for the identity to stay member
RenewMembership,
/// Certify an identity /// Certify an identity
Certify { target: u32 }, Certify { target: u32 },
/// Revoke an identity immediately /// Revoke an identity immediately
...@@ -40,6 +48,11 @@ pub enum Subcommand { ...@@ -40,6 +48,11 @@ pub enum Subcommand {
GenRevocDoc, GenRevocDoc,
/// Display member count /// Display member count
MemberCount, MemberCount,
/// Link an account to the identity
LinkAccount {
/// address of the account that has to be linked
address: AccountId,
},
} }
/// handle identity commands /// handle identity commands
...@@ -61,6 +74,12 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -61,6 +74,12 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
Subcommand::Confirm { name } => { Subcommand::Confirm { name } => {
confirm_identity(&data, name).await?; confirm_identity(&data, name).await?;
} }
Subcommand::Validate { index } => {
validate_identity(&data, index).await?;
}
Subcommand::RenewMembership => {
renew_membership(&data).await?;
}
Subcommand::Certify { target } => { Subcommand::Certify { target } => {
data = data.fetch_idty_index().await?; data = data.fetch_idty_index().await?;
// TODO fetch target username / key / index // TODO fetch target username / key / index
...@@ -69,7 +88,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -69,7 +88,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
} }
Subcommand::Revoke => { Subcommand::Revoke => {
data = data.fetch_idty_index().await?; data = data.fetch_idty_index().await?;
revoke_identity(data).await?; revoke_identity(&data).await?;
} }
Subcommand::GenRevocDoc => { Subcommand::GenRevocDoc => {
data = data.fetch_idty_index().await?; data = data.fetch_idty_index().await?;
...@@ -88,6 +107,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -88,6 +107,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
.unwrap() .unwrap()
) )
} }
Subcommand::LinkAccount { address } => {
data = data.fetch_idty_index().await?; // idty index required for payload
link_account(&data, address).await?;
}
}; };
Ok(()) Ok(())
...@@ -186,50 +209,42 @@ pub async fn get_identity_by_index( ...@@ -186,50 +209,42 @@ pub async fn get_identity_by_index(
/// created identity /// created identity
pub async fn create_identity(data: &Data, target: AccountId) -> Result<(), subxt::Error> { pub async fn create_identity(data: &Data, target: AccountId) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::identity::events::IdtyCreated,
.tx() StaticTxPayload<runtime::identity::calls::CreateIdentity>,
.sign_and_submit_then_watch( >(data, &runtime::tx().identity().create_identity(target))
&runtime::tx().identity().create_identity(target), .await
&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:?}");
}
Ok(())
} }
/// confirm identity /// confirm identity
pub async fn confirm_identity(data: &Data, name: String) -> Result<(), subxt::Error> { pub async fn confirm_identity(data: &Data, name: String) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::identity::events::IdtyConfirmed,
.tx() StaticTxPayload<runtime::identity::calls::ConfirmIdentity>,
.sign_and_submit_then_watch( >(data, &runtime::tx().identity().confirm_identity(name))
&runtime::tx().identity().confirm_identity(name), .await
&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>()? { /// confirm identity
println!("{e:?}"); pub async fn validate_identity(data: &Data, index: u32) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::identity::events::IdtyValidated,
StaticTxPayload<runtime::identity::calls::ValidateIdentity>,
>(data, &runtime::tx().identity().validate_identity(index))
.await
} }
Ok(())
/// renew membership
pub async fn renew_membership(data: &Data) -> Result<(), subxt::Error> {
submit_call_and_look_event::<
runtime::membership::events::MembershipRenewed,
StaticTxPayload<runtime::membership::calls::RenewMembership>,
>(data, &runtime::tx().membership().renew_membership())
.await
} }
/// generate revokation document and submit it immediately /// generate revokation document and submit it immediately
pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> { pub async fn revoke_identity(data: &Data) -> Result<(), subxt::Error> {
let (_payload, signature) = generate_revoc_doc(&data); let (_payload, signature) = generate_revoc_doc(&data);
// Transform signature to MultiSignature // Transform signature to MultiSignature
...@@ -237,24 +252,45 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> { ...@@ -237,24 +252,45 @@ pub async fn revoke_identity(data: Data) -> Result<(), subxt::Error> {
let signature = Signature(signature.0); let signature = Signature(signature.0);
let multisign = MultiSignature::Sr25519(signature); let multisign = MultiSignature::Sr25519(signature);
let progress = data submit_call_and_look_event::<
.client() runtime::identity::events::IdtyRemoved,
.tx() StaticTxPayload<runtime::identity::calls::RevokeIdentity>,
.sign_and_submit_then_watch( >(
data,
&runtime::tx() &runtime::tx()
.identity() .identity()
.revoke_identity(data.idty_index(), data.address(), multisign), .revoke_identity(data.idty_index(), data.address(), multisign),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
) )
.await?; .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>()? { type LinkAccountPayload = Vec<u8>;
println!("{e:?}"); /// generate link account document
pub fn generate_link_account(
data: &Data,
address: AccountId,
) -> (LinkAccountPayload, sp_core::sr25519::Signature) {
let payload = (b"link", data.genesis_hash, data.idty_index(), address).encode();
let signature = data.keypair().sign(&payload);
(payload, signature)
} }
Ok(())
/// link an account to the identity
pub async fn link_account(data: &Data, address: AccountId) -> Result<(), subxt::Error> {
let (_payload, signature) = generate_link_account(data, address.clone());
// this is a hack, see
// https://substrate.stackexchange.com/questions/10309/how-to-use-core-crypto-types-instead-of-runtime-types
let signature = Signature(signature.0);
submit_call_and_look_event::<
runtime::account::events::AccountLinked,
StaticTxPayload<runtime::identity::calls::LinkAccount>,
>(
data,
&runtime::tx()
.identity()
.link_account(address, NewOwnerKeySignature(signature)),
)
.await
} }
...@@ -176,21 +176,15 @@ pub async fn consume_oneshot_account_with_remaining( ...@@ -176,21 +176,15 @@ pub async fn consume_oneshot_account_with_remaining(
.fetch(&runtime::storage().system().number(), None) .fetch(&runtime::storage().system().number(), None)
.await? .await?
.unwrap(); .unwrap();
let progress = client
.tx() let call = &runtime::tx()
.sign_and_submit_then_watch(
&runtime::tx()
.oneshot_account() .oneshot_account()
.consume_oneshot_account_with_remaining( .consume_oneshot_account_with_remaining(
number, number,
if dest_oneshot { if dest_oneshot {
runtime::runtime_types::pallet_oneshot_account::types::Account::Oneshot( runtime::runtime_types::pallet_oneshot_account::types::Account::Oneshot(dest.into())
dest.into(),
)
} else { } else {
runtime::runtime_types::pallet_oneshot_account::types::Account::Normal( runtime::runtime_types::pallet_oneshot_account::types::Account::Normal(dest.into())
dest.into(),
)
}, },
if remaining_to_oneshot { if remaining_to_oneshot {
runtime::runtime_types::pallet_oneshot_account::types::Account::Oneshot( runtime::runtime_types::pallet_oneshot_account::types::Account::Oneshot(
...@@ -202,20 +196,11 @@ pub async fn consume_oneshot_account_with_remaining( ...@@ -202,20 +196,11 @@ pub async fn consume_oneshot_account_with_remaining(
) )
}, },
balance, balance,
), );
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
if data.args.no_wait { submit_call_and_look_event::<
return Ok(()); runtime::oneshot_account::events::OneshotAccountConsumed,
} StaticTxPayload<runtime::oneshot_account::calls::ConsumeOneshotAccountWithRemaining>,
let events = track_progress(progress).await?; >(data, call)
if let Some(e) = .await
events.find_first::<runtime::oneshot_account::events::OneshotAccountConsumed>()?
{
println!("{e:?}");
}
Ok(())
} }
...@@ -310,35 +310,21 @@ pub async fn online(data: &Data) -> Result<(), anyhow::Error> { ...@@ -310,35 +310,21 @@ pub async fn online(data: &Data) -> Result<(), anyhow::Error> {
Ok(()) Ok(())
} }
/// submit a certification and track progress /// submit a smith certification and track progress
pub async fn cert(data: &Data, receiver: u32) -> Result<(), anyhow::Error> { pub async fn cert(data: &Data, receiver: u32) -> Result<(), anyhow::Error> {
let progress = data let progress = submit_call(
.client() data,
.tx()
.sign_and_submit_then_watch(
&runtime::tx() &runtime::tx()
.smith_cert() .smith_cert()
.add_cert(data.idty_index(), receiver), .add_cert(data.idty_index(), receiver),
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await?;
if data.args.no_wait { if data.args.no_wait {
return Ok(()); return Ok(());
} }
let events = track_progress(progress).await?; let events = track_progress(progress).await?;
// look for the expected event // look for the expected event
let new_cert_event = events.find_first::<runtime::smith_cert::events::NewCert>()?; look_event::<runtime::smith_cert::events::NewCert>(&events)?;
let renew_cert_event = events.find_first::<runtime::smith_cert::events::RenewedCert>()?; look_event::<runtime::smith_cert::events::RenewedCert>(&events)?;
if let Some(event) = new_cert_event {
println!("{event:?}");
}
if let Some(event) = renew_cert_event {
println!("{event:?}");
}
Ok(()) Ok(())
} }
...@@ -2,19 +2,9 @@ use crate::*; ...@@ -2,19 +2,9 @@ use crate::*;
/// set sudo key /// set sudo key
pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> { pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::sudo::events::KeyChanged,
.tx() StaticTxPayload<runtime::sudo::calls::SetKey>,
.sign_and_submit_then_watch( >(data, &runtime::tx().sudo().set_key(new_key.into()))
&runtime::tx().sudo().set_key(new_key.into()), .await
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
if data.args.no_wait {
return Ok(());
}
let _ = track_progress(progress).await?; // TODO
Ok(())
} }
...@@ -78,25 +78,10 @@ pub async fn transfer_multiple( ...@@ -78,25 +78,10 @@ pub async fn transfer_multiple(
}) })
}) })
.collect(); .collect();
// wrap these calls in a batch call // wrap these calls in a batch call
let progress = data submit_call_and_look_event::<
.client() runtime::utility::events::BatchCompleted,
.tx() StaticTxPayload<runtime::utility::calls::Batch>,
.sign_and_submit_then_watch( >(data, &runtime::tx().utility().batch(transactions))
&runtime::tx().utility().batch(transactions), .await
&PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(),
)
.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>()? {
println!("{e:?}");
}
Ok(())
} }
...@@ -15,7 +15,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -15,7 +15,7 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
// match subcommand // match subcommand
match command { match command {
Subcommand::Claim => { Subcommand::Claim => {
claim_ud(data).await?; claim_ud(&data).await?;
} }
}; };
...@@ -23,24 +23,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<( ...@@ -23,24 +23,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<(
} }
/// claim universal dividend /// claim universal dividend
pub async fn claim_ud(data: Data) -> Result<(), anyhow::Error> { pub async fn claim_ud(data: &Data) -> Result<(), subxt::Error> {
let progress = data submit_call_and_look_event::<
.client() runtime::universal_dividend::events::UdsClaimed,
.tx() StaticTxPayload<runtime::universal_dividend::calls::ClaimUds>,
.sign_and_submit_then_watch( >(data, &runtime::tx().universal_dividend().claim_uds())
&runtime::tx().universal_dividend().claim_uds(), .await
&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::universal_dividend::events::UdsClaimed>()? {
println!("{e:?}");
}
Ok(())
} }
...@@ -27,6 +27,25 @@ impl std::default::Default for Config { ...@@ -27,6 +27,25 @@ impl std::default::Default for Config {
} }
} }
impl std::fmt::Display for Config {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let secret = if self.secret.is_some() {
"(secret defined)"
} else {
"(no secret)"
};
let address = if let Some(address) = &self.address {
format!("{}", address)
} else {
"(no address)".to_string()
};
writeln!(f, "Ğcli config")?;
writeln!(f, "duniter endpoint {}", self.duniter_endpoint)?;
writeln!(f, "indexer endpoint {}", self.indexer_endpoint)?;
write!(f, "address {address} {secret}")
}
}
/// load config file and manage error if could not /// load config file and manage error if could not
pub fn load_conf() -> Config { pub fn load_conf() -> Config {
match confy::load(APP_NAME, None) { match confy::load(APP_NAME, None) {
...@@ -68,7 +87,7 @@ pub fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> { ...@@ -68,7 +87,7 @@ pub fn handle_command(data: Data, command: Subcommand) -> anyhow::Result<()> {
); );
} }
Subcommand::Show => { Subcommand::Show => {
println!("{:?}", data.cfg); println!("{}", data.cfg);
} }
Subcommand::Save => { Subcommand::Save => {
confy::store(APP_NAME, None, &data.cfg).expect("unable to write config"); confy::store(APP_NAME, None, &data.cfg).expect("unable to write config");
......
...@@ -92,7 +92,7 @@ pub enum Subcommand { ...@@ -92,7 +92,7 @@ pub enum Subcommand {
Config(conf::Subcommand), Config(conf::Subcommand),
} }
/// maint function /// main function
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), GcliError> { async fn main() -> Result<(), GcliError> {
// init logger // init logger
......
// #[allow(clippy::enum_variant_names)]
#[cfg(feature = "gdev")] #[cfg(feature = "gdev")]
#[subxt::subxt( #[subxt::subxt(
runtime_metadata_path = "res/metadata.scale", runtime_metadata_path = "res/metadata.scale",
...@@ -5,8 +6,8 @@ ...@@ -5,8 +6,8 @@
)] )]
pub mod runtime { pub mod runtime {
// IF NEEDED // IF NEEDED
// #[subxt(substitute_type = "spcore::sr25519::Signature")] // #[subxt(substitute_type = "sp_core::sr25519::Signature")]
// use crate::gdev::runtime_types::sp_core::sr25519::Signature; // use crate::runtime::runtime_types::sp_core::sr25519::Signature;
} }
// declare custom types // declare custom types
......
...@@ -28,24 +28,40 @@ pub async fn submit_call_and_look_event<E: std::fmt::Debug + StaticEvent, Call: ...@@ -28,24 +28,40 @@ pub async fn submit_call_and_look_event<E: std::fmt::Debug + StaticEvent, Call:
data: &Data, data: &Data,
call: &Call, call: &Call,
) -> Result<(), subxt::Error> { ) -> Result<(), subxt::Error> {
let progress = data // submit call
.client() 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() .tx()
.sign_and_submit_then_watch( .sign_and_submit_then_watch(
call, call,
&PairSigner::new(data.keypair()), &PairSigner::new(data.keypair()),
BaseExtrinsicParamsBuilder::new(), BaseExtrinsicParamsBuilder::new(),
) )
.await?; .await
if data.args.no_wait {
return Ok(());
} }
let events = track_progress(progress).await?;
/// 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>()? { if let Some(e) = events.find_first::<E>()? {
println!("{e:?}"); println!("{e:?}");
} }
Ok(()) Ok(())
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment