use crate::abi;
use crate::staking::Staking;
use crate::tx::Tx;
use crate::wallet::utils::core_felt_to_rs;
use crate::wallet::WalletExecutor;
use krusty_kms_common::address::Address;
use krusty_kms_common::amount::Amount;
use krusty_kms_common::token::Token;
use krusty_kms_common::Result;
use starknet_rust::core::types::Call;
pub struct TxBuilder<'w> {
wallet: &'w dyn WalletExecutor,
calls: Vec<Call>,
}
impl<'w> TxBuilder<'w> {
pub fn new(wallet: &'w dyn WalletExecutor) -> Self {
Self {
wallet,
calls: Vec::new(),
}
}
#[allow(clippy::should_implement_trait)]
pub fn add(mut self, call: Call) -> Self {
self.calls.push(call);
self
}
pub fn approve(self, token: &Token, spender: &Address, amount: &Amount) -> Self {
let (low, high) = amount.to_u256();
let call = Call {
to: core_felt_to_rs(token.address.as_felt()),
selector: *abi::erc20::APPROVE,
calldata: vec![
core_felt_to_rs(spender.as_felt()),
core_felt_to_rs(low),
core_felt_to_rs(high),
],
};
self.add(call)
}
pub fn transfer(self, token: &Token, to: &Address, amount: &Amount) -> Self {
let (low, high) = amount.to_u256();
let call = Call {
to: core_felt_to_rs(token.address.as_felt()),
selector: *abi::erc20::TRANSFER,
calldata: vec![
core_felt_to_rs(to.as_felt()),
core_felt_to_rs(low),
core_felt_to_rs(high),
],
};
self.add(call)
}
pub fn enter_pool(self, staking: &Staking, amount: &Amount, reward_address: &Address) -> Self {
let calls = staking.populate_enter(amount, reward_address);
let mut s = self;
for call in calls {
s = s.add(call);
}
s
}
pub fn add_to_pool(self, staking: &Staking, amount: &Amount) -> Self {
let calls = staking.populate_add(amount);
let mut s = self;
for call in calls {
s = s.add(call);
}
s
}
pub fn claim_rewards(self, staking: &Staking, reward_address: &Address) -> Self {
let call = staking.populate_claim_rewards(reward_address);
self.add(call)
}
pub fn exit_intent(self, staking: &Staking, amount: &Amount) -> Self {
let call = staking.populate_exit_intent(amount);
self.add(call)
}
pub fn exit_pool(self, staking: &Staking) -> Self {
let call = staking.populate_exit();
self.add(call)
}
pub fn calls(&self) -> &[Call] {
&self.calls
}
pub async fn estimate_fee(&self) -> Result<starknet_rust::core::types::FeeEstimate> {
self.wallet.estimate_fee(self.calls.clone()).await
}
pub async fn send(self) -> Result<Tx> {
self.wallet.execute(self.calls).await
}
}