Skip to main content

altius_tx_sdk/
nonce.rs

1//! Nonce manager for handling transaction nonces.
2
3use crate::rpc::RpcClient;
4use crate::Result;
5use alloy_primitives::Address;
6use std::sync::Arc;
7use tokio::sync::Mutex;
8
9/// NonceManager for managing transaction nonces
10pub struct NonceManager {
11    rpc: Arc<RpcClient>,
12    address: Address,
13    nonce: Mutex<Option<u64>>,
14}
15
16impl NonceManager {
17    /// Create a new nonce manager
18    pub fn new(rpc: Arc<RpcClient>, address: Address) -> Self {
19        Self {
20            rpc,
21            address,
22            nonce: Mutex::new(None),
23        }
24    }
25
26    /// Get the current nonce (cached)
27    pub async fn get_nonce(&self) -> Result<u64> {
28        let mut guard = self.nonce.lock().await;
29        if let Some(nonce) = *guard {
30            return Ok(nonce);
31        }
32
33        // Fetch from RPC
34        let nonce = self.rpc.get_transaction_count(self.address, "pending").await?;
35        *guard = Some(nonce);
36        Ok(nonce)
37    }
38
39    /// Get and increment the nonce
40    pub async fn get_and_increment_nonce(&self) -> Result<u64> {
41        let mut guard = self.nonce.lock().await;
42        let nonce = if let Some(n) = *guard {
43            n
44        } else {
45            // Fetch from RPC
46            self.rpc.get_transaction_count(self.address, "pending").await?
47        };
48
49        *guard = Some(nonce + 1);
50        Ok(nonce)
51    }
52
53    /// Reset the nonce cache (useful after errors)
54    pub fn reset_nonce(&self) {
55        let mut guard = self.nonce.blocking_lock();
56        *guard = None;
57    }
58
59    /// Set a specific nonce
60    pub async fn set_nonce(&self, nonce: u64) {
61        let mut guard = self.nonce.lock().await;
62        *guard = Some(nonce);
63    }
64}
65
66/// Create a new nonce manager (convenience function)
67pub fn create_nonce_manager(rpc: Arc<RpcClient>, address: Address) -> NonceManager {
68    NonceManager::new(rpc, address)
69}