kabu_broadcast_accounts/signers/
initialize_actor.rs1use alloy_primitives::{B256, Bytes, hex};
2use eyre::eyre;
3use kabu_core_components::Component;
4use std::sync::Arc;
5use tokio::sync::RwLock;
6use tracing::info;
7
8use kabu_core_blockchain::Blockchain;
9use kabu_types_entities::{AccountNonceAndBalanceState, KeyStore, LoomTxSigner, TxSigners};
10use reth_ethereum_primitives::EthPrimitives;
11use reth_node_types::NodePrimitives;
12
13#[derive(Clone)]
15pub struct InitializeSignersOneShotBlockingComponent<LDT: NodePrimitives> {
16 key: Option<Vec<u8>>,
17 signers: Option<Arc<RwLock<TxSigners<LDT>>>>,
18 monitor: Option<Arc<RwLock<AccountNonceAndBalanceState>>>,
19}
20
21async fn initialize_signers_one_shot_worker(
22 key: Vec<u8>,
23 signers: Arc<RwLock<TxSigners<EthPrimitives>>>,
24 monitor: Arc<RwLock<AccountNonceAndBalanceState>>,
25) -> eyre::Result<()> {
26 let new_signer = signers.write().await.add_privkey(Bytes::from(key));
27 monitor.write().await.add_account(new_signer.address());
28 info!("New signer added {:?}", new_signer.address());
29 Ok(())
30}
31
32impl<LDT: NodePrimitives> InitializeSignersOneShotBlockingComponent<LDT> {
33 pub fn new(key: Option<Vec<u8>>) -> InitializeSignersOneShotBlockingComponent<LDT> {
34 let key = key.unwrap_or_else(|| B256::random().to_vec());
35
36 InitializeSignersOneShotBlockingComponent { key: Some(key), signers: None, monitor: None }
37 }
38
39 pub fn new_from_encrypted_env() -> InitializeSignersOneShotBlockingComponent<LDT> {
40 let key = match std::env::var("DATA") {
41 Ok(priv_key_enc) => {
42 let keystore = KeyStore::new();
43 let key = keystore.encrypt_once(hex::decode(priv_key_enc).unwrap().as_slice()).unwrap();
44 Some(key)
45 }
46 _ => None,
47 };
48
49 InitializeSignersOneShotBlockingComponent { key, signers: None, monitor: None }
50 }
51
52 pub fn new_from_encrypted_key(priv_key_enc: Vec<u8>) -> InitializeSignersOneShotBlockingComponent<LDT> {
53 let keystore = KeyStore::new();
54 let key = keystore.encrypt_once(priv_key_enc.as_slice()).unwrap();
55
56 InitializeSignersOneShotBlockingComponent { key: Some(key), signers: None, monitor: None }
57 }
58
59 pub fn on_bc(self, bc: &Blockchain<LDT>) -> Self {
60 Self { monitor: Some(bc.nonce_and_balance()), ..self }
61 }
62
63 pub fn with_signers(self, signers: Arc<RwLock<TxSigners<LDT>>>) -> Self {
64 Self { signers: Some(signers), ..self }
65 }
66
67 pub fn with_monitor(self, monitor: Arc<RwLock<AccountNonceAndBalanceState>>) -> Self {
68 Self { monitor: Some(monitor), ..self }
69 }
70}
71
72impl Component for InitializeSignersOneShotBlockingComponent<EthPrimitives> {
73 fn spawn(self, executor: reth_tasks::TaskExecutor) -> eyre::Result<()> {
74 let name = self.name();
75 let key = self.key.ok_or_else(|| eyre!("No signer keys found"))?;
76 let signers = self.signers.ok_or_else(|| eyre!("Signers not initialized"))?;
77 let monitor = self.monitor.ok_or_else(|| eyre!("Monitor not initialized"))?;
78
79 executor.spawn_critical(name, async move {
80 if let Err(e) = initialize_signers_one_shot_worker(key, signers, monitor).await {
81 tracing::error!("Initialize signers failed: {}", e);
82 }
83 });
84 Ok(())
85 }
86
87 fn name(&self) -> &'static str {
88 "InitializeSignersOneShotBlockingComponent"
89 }
90}