use crate::rpc::RpcClient;
use crate::Result;
use alloy_primitives::Address;
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct NonceManager {
rpc: Arc<RpcClient>,
address: Address,
nonce: Mutex<Option<u64>>,
}
impl NonceManager {
pub fn new(rpc: Arc<RpcClient>, address: Address) -> Self {
Self {
rpc,
address,
nonce: Mutex::new(None),
}
}
pub async fn get_nonce(&self) -> Result<u64> {
let mut guard = self.nonce.lock().await;
if let Some(nonce) = *guard {
return Ok(nonce);
}
let nonce = self.rpc.get_transaction_count(self.address, "pending").await?;
*guard = Some(nonce);
Ok(nonce)
}
pub async fn get_and_increment_nonce(&self) -> Result<u64> {
let mut guard = self.nonce.lock().await;
let nonce = if let Some(n) = *guard {
n
} else {
self.rpc.get_transaction_count(self.address, "pending").await?
};
*guard = Some(nonce + 1);
Ok(nonce)
}
pub fn reset_nonce(&self) {
let mut guard = self.nonce.blocking_lock();
*guard = None;
}
pub async fn set_nonce(&self, nonce: u64) {
let mut guard = self.nonce.lock().await;
*guard = Some(nonce);
}
}
pub fn create_nonce_manager(rpc: Arc<RpcClient>, address: Address) -> NonceManager {
NonceManager::new(rpc, address)
}