use std::ops::Deref;
use crate::bundle_builder::{BundleBuilder, BundleOptions};
use solana_sdk::signer::Signer;
use super::MakeBundleBuilder;
pub struct EstimateFee<T> {
builder: T,
compute_unit_price_micro_lamports: Option<u64>,
compute_unit_min_priority_lamports: Option<u64>,
}
impl<T> EstimateFee<T> {
pub fn new(
builder: T,
compute_unit_price_micro_lamports: Option<u64>,
compute_unit_min_priority_lamports: Option<u64>,
) -> Self {
Self {
builder,
compute_unit_price_micro_lamports,
compute_unit_min_priority_lamports,
}
}
}
pub trait SetExecutionFee {
fn is_execution_fee_estimation_required(&self) -> bool {
true
}
fn set_execution_fee(&mut self, lamports: u64) -> &mut Self;
}
impl<'a, C: Deref<Target = impl Signer> + Clone, T> MakeBundleBuilder<'a, C> for EstimateFee<T>
where
T: SetExecutionFee,
T: MakeBundleBuilder<'a, C>,
{
async fn build_with_options(
&mut self,
options: BundleOptions,
) -> crate::Result<BundleBuilder<'a, C>> {
let mut tx = self.builder.build_with_options(options.clone()).await?;
if self.builder.is_execution_fee_estimation_required() {
let lamports = tx.build()?.estimate_execution_fee(
self.compute_unit_price_micro_lamports,
self.compute_unit_min_priority_lamports,
);
self.builder.set_execution_fee(lamports);
tracing::info!(%lamports, "execution fee estimated");
tx = self.builder.build_with_options(options).await?;
}
Ok(tx)
}
}