gmsol_solana_utils/make_bundle_builder/
surround.rs

1use std::ops::Deref;
2
3use crate::{
4    bundle_builder::{BundleBuilder, BundleOptions},
5    transaction_builder::TransactionBuilder,
6};
7use solana_sdk::signer::Signer;
8
9use super::MakeBundleBuilder;
10
11/// Surround transaction.
12pub struct Surround<'a, C, T> {
13    builder: T,
14    pre_transaction_stack: Vec<TransactionBuilder<'a, C>>,
15    post_transaction_queue: Vec<TransactionBuilder<'a, C>>,
16}
17
18impl<C, T> From<T> for Surround<'_, C, T> {
19    fn from(builder: T) -> Self {
20        Self {
21            builder,
22            pre_transaction_stack: vec![],
23            post_transaction_queue: vec![],
24        }
25    }
26}
27
28impl<'a, C, T> Surround<'a, C, T> {
29    /// Prepend a transaction to the pre-transaction list.
30    pub fn pre_transaction(&mut self, transaction: TransactionBuilder<'a, C>) -> &mut Self {
31        self.pre_transaction_stack.push(transaction);
32        self
33    }
34
35    /// Append a transaction to the post-transaction list.
36    pub fn post_transaction(&mut self, transaction: TransactionBuilder<'a, C>) -> &mut Self {
37        self.post_transaction_queue.push(transaction);
38        self
39    }
40}
41
42impl<'a, C: Deref<Target = impl Signer> + Clone, T> MakeBundleBuilder<'a, C> for Surround<'a, C, T>
43where
44    T: MakeBundleBuilder<'a, C>,
45{
46    async fn build_with_options(
47        &mut self,
48        options: BundleOptions,
49    ) -> crate::Result<BundleBuilder<'a, C>> {
50        let mut bundle = self.builder.build_with_options(options).await?;
51
52        if !self.pre_transaction_stack.is_empty() {
53            let mut pre_bundle = bundle.try_clone_empty()?;
54            // FILO insertion.
55            for txn in self.pre_transaction_stack.iter().rev() {
56                pre_bundle.push(txn.clone())?;
57            }
58
59            pre_bundle.append(bundle, false)?;
60            bundle = pre_bundle;
61        }
62
63        bundle.push_many(self.post_transaction_queue.iter().cloned(), false)?;
64
65        Ok(bundle)
66    }
67}