gmsol_solana_utils/make_bundle_builder/
surround.rs1use 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
11pub 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 pub fn pre_transaction(&mut self, transaction: TransactionBuilder<'a, C>) -> &mut Self {
31 self.pre_transaction_stack.push(transaction);
32 self
33 }
34
35 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 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}