use crate::{Error, algod::v2::Algod};
use algonaut_core::TransactionId;
use algonaut_model::algod::PendingTransactionResponse;
use instant::Instant;
use std::time::Duration;
const DEFAULT_CONFIRM_TIMEOUT: Duration = Duration::from_secs(60);
#[derive(Debug, Clone)]
pub struct PendingSubmission {
algod: Algod,
transaction_id: TransactionId,
}
impl PendingSubmission {
pub(crate) fn new(algod: Algod, transaction_id: TransactionId) -> Self {
Self {
algod,
transaction_id,
}
}
pub fn transaction_id(&self) -> &TransactionId {
&self.transaction_id
}
pub async fn confirm(self) -> Result<PendingTransactionResponse, Error> {
self.confirm_with(DEFAULT_CONFIRM_TIMEOUT).await
}
pub async fn confirm_with(
self,
timeout: Duration,
) -> Result<PendingTransactionResponse, Error> {
let start = Instant::now();
let mut last_round = self.algod.status().await?.last_round;
loop {
let pending = self.algod.pending_transaction(&self.transaction_id).await?;
if pending.confirmed_round.is_some() {
return Ok(pending);
}
if !pending.pool_error.is_empty() {
return Err(Error::PendingTransactionPoolError {
reason: pending.pool_error,
});
}
if start.elapsed() >= timeout {
return Err(Error::PendingTransactionTimeout { timeout });
}
last_round = self.algod.status_after_block(last_round).await?.last_round;
}
}
}