use color_eyre::Result; use subxt::{ ext::sp_core::{Pair as PairT, sr25519::Pair}, tx::{PairSigner, TxProgress}, OnlineClient, }; use tokio::sync::mpsc::UnboundedSender; use crate::{ action::Action, types::{ActionLevel, ActionTarget}, casper::{CasperExtrinsicParamsBuilder, CasperConfig}, casper_network, }; pub async fn transfer_balance( action_tx: &UnboundedSender, api: &OnlineClient, sender: &[u8; 32], receiver: &[u8; 32], amount: &u128, mut maybe_nonce: Option<&mut u32>, ) -> Result>> { let receiver_id = subxt::utils::MultiAddress::Id( subxt::utils::AccountId32::from(*receiver) ); let transfer_tx = casper_network::tx() .balances() .transfer_allow_death(receiver_id, *amount); let tx_params = match maybe_nonce { Some(ref mut nonce) => { **nonce = nonce.saturating_add(1); CasperExtrinsicParamsBuilder::new() .nonce(nonce.saturating_sub(1) as u64) .build() }, None => CasperExtrinsicParamsBuilder::new().build(), }; let pair = Pair::from_seed(sender); let signer = PairSigner::::new(pair); match api .tx() .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) .await { Ok(tx_progress) => { action_tx.send(Action::EventLog( format!("transfer transaction {} sent", tx_progress.extrinsic_hash()), ActionLevel::Info, ActionTarget::WalletLog))?; Ok(tx_progress) }, Err(err) => { action_tx.send(Action::EventLog( format!("error during transfer: {err}"), ActionLevel::Error, ActionTarget::WalletLog))?; Err(err.into()) } } } pub async fn bond_extra( action_tx: &UnboundedSender, api: &OnlineClient, sender: &[u8; 32], amount: &u128, mut maybe_nonce: Option<&mut u32>, ) -> Result>> { let transfer_tx = casper_network::tx() .staking() .bond_extra(*amount); let tx_params = match maybe_nonce { Some(ref mut nonce) => { **nonce = nonce.saturating_add(1); CasperExtrinsicParamsBuilder::new() .nonce(nonce.saturating_sub(1) as u64) .build() }, None => CasperExtrinsicParamsBuilder::new().build(), }; let pair = Pair::from_seed(sender); let signer = PairSigner::::new(pair); match api .tx() .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) .await { Ok(tx_progress) => { action_tx.send(Action::EventLog( format!("bond extra transaction {} sent", tx_progress.extrinsic_hash()), ActionLevel::Info, ActionTarget::ValidatorLog))?; Ok(tx_progress) }, Err(err) => { action_tx.send(Action::EventLog( format!("error during bond extra: {err}"), ActionLevel::Error, ActionTarget::ValidatorLog))?; Err(err.into()) } } } pub async fn bond( action_tx: &UnboundedSender, api: &OnlineClient, sender: &[u8; 32], amount: &u128, mut maybe_nonce: Option<&mut u32>, ) -> Result>> { // auto-stake everything by now let reward_destination = casper_network::runtime_types::pallet_staking::RewardDestination::Staked; let transfer_tx = casper_network::tx() .staking() .bond(*amount, reward_destination); let tx_params = match maybe_nonce { Some(ref mut nonce) => { **nonce = nonce.saturating_add(1); CasperExtrinsicParamsBuilder::new() .nonce(nonce.saturating_sub(1) as u64) .build() }, None => CasperExtrinsicParamsBuilder::new().build(), }; let pair = Pair::from_seed(sender); let signer = PairSigner::::new(pair); match api .tx() .sign_and_submit_then_watch(&transfer_tx, &signer, tx_params) .await { Ok(tx_progress) => { action_tx.send(Action::EventLog( format!("bond transaction {} sent", tx_progress.extrinsic_hash()), ActionLevel::Info, ActionTarget::ValidatorLog))?; Ok(tx_progress) }, Err(err) => { action_tx.send(Action::EventLog( format!("error during bond: {err}"), ActionLevel::Error, ActionTarget::ValidatorLog))?; Err(err.into()) } } }