Newer
Older
Nicolas80
committed
use sea_orm::DbErr;
/// track progress of transaction on the network
/// until it is in block with success or failure
pub async fn track_progress(
mut progress: TxProgress,
) -> Result<ExtrinsicEvents<Runtime>, subxt::Error> {
loop {
println!("transaction submitted to the network, waiting 6 seconds...");
}
TxStatus::InBestBlock(in_block) => break in_block,
TxStatus::Invalid { message } => {
println!("Invalid {message}");
}
_ => continue,
}
}
}
.wait_for_success()
.await
}
pub async fn submit_call_and_look_event<
E: std::fmt::Debug + StaticEvent + DisplayEvent,
let progress = submit_call(data, payload).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
) -> Result<TxProgress, subxt::Error> {
// get account nonce manually to be based on last block and not last finalized
let nonce = data
.legacy_rpc_methods() // see issue #32
.await
.system_account_next_index(&data.address())
.await?;
// sign and submit
Nicolas80
committed
match data.keypair().await {
KeyPair::Sr25519(keypair) => data.client().tx().create_signed_offline(
payload,
&PairSigner::<Runtime, sp_core::sr25519::Pair>::new(keypair),
DefaultExtrinsicParamsBuilder::new().nonce(nonce).build(),
Nicolas80
committed
KeyPair::Ed25519(keypair) => data.client().tx().create_signed_offline(
payload,
&PairSigner::<Runtime, sp_core::ed25519::Pair>::new(keypair),
DefaultExtrinsicParamsBuilder::new().nonce(nonce).build(),
),
}?
.submit_and_watch()
.await
pub fn look_event<E: std::fmt::Debug + StaticEvent + DisplayEvent>(
data: &Data,
events: &ExtrinsicEvents<Runtime>,
) -> Result<(), subxt::Error> {
if let Some(e) = events.find_first::<E>()? {
// print nothing, this could happen for
// - new cert vs renew cert
// - new smith cert and smith "promotion"
// println!("(no event of type {})", std::any::type_name::<E>())
/// custom error type intended to provide more convenient error message to user
#[derive(Debug)]
pub enum GcliError {
/// error coming from subxt
Subxt(subxt::Error),
/// error coming from duniter
Nicolas80
committed
#[allow(dead_code)]
Duniter(String),
/// error coming from indexer
Nicolas80
committed
#[allow(dead_code)]
Nicolas80
committed
/// error coming from database
#[allow(dead_code)]
DatabaseError(DbErr),
/// logic error (illegal operation or security)
Nicolas80
committed
#[allow(dead_code)]
Nicolas80
committed
#[allow(dead_code)]
Input(String),
/// error coming from anyhow (to be removed)
Nicolas80
committed
#[allow(dead_code)]
Nicolas80
committed
#[allow(dead_code)]
}
impl std::fmt::Display for GcliError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
// prettier runtime error
GcliError::Subxt(subxt::Error::Runtime(e)) => {
write!(f, "{e}")
}
// debug log for detailed error
_ => write!(f, "{:?}", self),
}
}
}
impl std::error::Error for GcliError {}
impl From<subxt::Error> for GcliError {
fn from(e: subxt::Error) -> GcliError {
GcliError::Subxt(e)
}
}
impl From<anyhow::Error> for GcliError {
fn from(e: anyhow::Error) -> GcliError {
GcliError::Anyhow(e)
}
}
impl From<confy::ConfyError> for GcliError {
fn from(e: confy::ConfyError) -> GcliError {
GcliError::Anyhow(e.into())
}
}
impl From<std::io::Error> for GcliError {
fn from(error: std::io::Error) -> Self {
GcliError::IoError(error)
}
}