pub mod builder;
pub use builder::TxBuilder;
use krusty_kms_common::network::NetworkPreset;
use krusty_kms_common::{KmsError, Result};
use starknet_rust::providers::jsonrpc::{HttpTransport, JsonRpcClient};
use starknet_rust::providers::Provider;
use std::sync::Arc;
type StarknetRsFelt = starknet_rust::core::types::Felt;
pub struct Tx {
hash: StarknetRsFelt,
provider: Arc<JsonRpcClient<HttpTransport>>,
network: NetworkPreset,
}
pub struct WaitOptions {
pub interval_secs: u64,
pub timeout_secs: u64,
}
impl Default for WaitOptions {
fn default() -> Self {
Self {
interval_secs: 5,
timeout_secs: 120,
}
}
}
impl Tx {
pub fn new(
hash: StarknetRsFelt,
provider: Arc<JsonRpcClient<HttpTransport>>,
network: NetworkPreset,
) -> Self {
Self {
hash,
provider,
network,
}
}
pub fn hash(&self) -> StarknetRsFelt {
self.hash
}
pub fn hash_hex(&self) -> String {
format!("{:#066x}", self.hash)
}
pub async fn wait(
&self,
options: Option<WaitOptions>,
) -> Result<starknet_rust::core::types::TransactionReceipt> {
let opts = options.unwrap_or_default();
let deadline =
tokio::time::Instant::now() + tokio::time::Duration::from_secs(opts.timeout_secs);
let interval = tokio::time::Duration::from_secs(opts.interval_secs);
loop {
if tokio::time::Instant::now() >= deadline {
return Err(KmsError::Timeout(format!(
"Transaction {} not accepted within {}s",
self.hash_hex(),
opts.timeout_secs
)));
}
match self.receipt().await {
Ok(receipt) => return Ok(receipt),
Err(_) => {
tokio::time::sleep(interval).await;
}
}
}
}
pub async fn receipt(&self) -> Result<starknet_rust::core::types::TransactionReceipt> {
let receipt = self
.provider
.get_transaction_receipt(self.hash)
.await
.map_err(|e| KmsError::TransactionError(e.to_string()))?;
use starknet_rust::core::types::TransactionReceiptWithBlockInfo;
let TransactionReceiptWithBlockInfo { receipt, .. } = receipt;
Ok(receipt)
}
pub fn explorer_url(&self) -> String {
self.network.explorer_tx_url(&self.hash_hex())
}
}