1use crate::rpc::RpcClient;
4use crate::Result;
5use alloy_primitives::Address;
6use std::sync::Arc;
7use tokio::sync::Mutex;
8
9pub struct NonceManager {
11 rpc: Arc<RpcClient>,
12 address: Address,
13 nonce: Mutex<Option<u64>>,
14}
15
16impl NonceManager {
17 pub fn new(rpc: Arc<RpcClient>, address: Address) -> Self {
19 Self {
20 rpc,
21 address,
22 nonce: Mutex::new(None),
23 }
24 }
25
26 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 let nonce = self.rpc.get_transaction_count(self.address, "pending").await?;
35 *guard = Some(nonce);
36 Ok(nonce)
37 }
38
39 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 self.rpc.get_transaction_count(self.address, "pending").await?
47 };
48
49 *guard = Some(nonce + 1);
50 Ok(nonce)
51 }
52
53 pub fn reset_nonce(&self) {
55 let mut guard = self.nonce.blocking_lock();
56 *guard = None;
57 }
58
59 pub async fn set_nonce(&self, nonce: u64) {
61 let mut guard = self.nonce.lock().await;
62 *guard = Some(nonce);
63 }
64}
65
66pub fn create_nonce_manager(rpc: Arc<RpcClient>, address: Address) -> NonceManager {
68 NonceManager::new(rpc, address)
69}