gmsol_solana_utils/make_bundle_builder/
mod.rs

1/// Estimate Execution Fee.
2pub mod estimate_fee;
3
4/// Surround transaction.
5pub mod surround;
6
7use std::{future::Future, ops::Deref};
8
9use solana_sdk::signer::Signer;
10
11use crate::{
12    bundle_builder::{BundleBuilder, BundleOptions},
13    transaction_builder::TransactionBuilder,
14};
15
16pub use self::{
17    estimate_fee::{EstimateFee, SetExecutionFee},
18    surround::Surround,
19};
20
21/// Builder for [`BundleBuilder`]s.
22pub trait MakeBundleBuilder<'a, C> {
23    /// Build with options.
24    fn build_with_options(
25        &mut self,
26        options: BundleOptions,
27    ) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>>;
28
29    /// Build.
30    fn build(&mut self) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
31        self.build_with_options(Default::default())
32    }
33}
34
35impl<'a, C, T> MakeBundleBuilder<'a, C> for &mut T
36where
37    T: MakeBundleBuilder<'a, C>,
38{
39    fn build(&mut self) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
40        (**self).build()
41    }
42
43    fn build_with_options(
44        &mut self,
45        options: BundleOptions,
46    ) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
47        (**self).build_with_options(options)
48    }
49}
50
51/// Extension trait for [`MakeBundleBuilder`].
52pub trait MakeBundleBuilderExt<'a, C>: MakeBundleBuilder<'a, C> {
53    /// Surround the current builder.
54    fn surround(self) -> Surround<'a, C, Self>
55    where
56        Self: Sized,
57    {
58        self.into()
59    }
60}
61
62impl<'a, C, T: MakeBundleBuilder<'a, C> + ?Sized> MakeBundleBuilderExt<'a, C> for T {}
63
64impl<'a, C: Deref<Target = impl Signer> + Clone> MakeBundleBuilder<'a, C>
65    for TransactionBuilder<'a, C>
66{
67    async fn build_with_options(
68        &mut self,
69        options: BundleOptions,
70    ) -> crate::Result<BundleBuilder<'a, C>> {
71        self.clone().into_bundle_with_options(options)
72    }
73}
74
75/// Make bundle builder that can only be used once.
76pub struct OnceMakeBundleBuilder<'a, C>(Option<BundleBuilder<'a, C>>);
77
78impl<'a, C> From<BundleBuilder<'a, C>> for OnceMakeBundleBuilder<'a, C> {
79    fn from(value: BundleBuilder<'a, C>) -> Self {
80        Self(Some(value))
81    }
82}
83
84/// Create a [`MakeBundleBuilder`] from a [`BundleBuilder`].
85pub fn once_make_bundle<C>(bundle: BundleBuilder<C>) -> OnceMakeBundleBuilder<'_, C> {
86    bundle.into()
87}
88
89impl<'a, C> MakeBundleBuilder<'a, C> for OnceMakeBundleBuilder<'a, C> {
90    async fn build_with_options(
91        &mut self,
92        options: BundleOptions,
93    ) -> crate::Result<BundleBuilder<'a, C>> {
94        let mut bundle = self
95            .0
96            .take()
97            .ok_or_else(|| crate::Error::custom("`OnceMakeBundleBuilder` can only be used once"))?;
98        bundle.set_options(options);
99        Ok(bundle)
100    }
101}