Skip to main content

foundry_primitives/network/
transaction.rs

1use alloy_consensus::{
2    BlobTransactionSidecar, BlobTransactionSidecarEip7594, BlobTransactionSidecarVariant,
3};
4use alloy_network::{AnyNetwork, Network, TransactionBuilder};
5use alloy_primitives::{Address, B256, U256};
6use alloy_rpc_types::SignedAuthorization;
7use tempo_alloy::TempoNetwork;
8
9/// Composite transaction builder trait for Foundry transactions.
10///
11/// This extends the base `TransactionBuilder` trait with the same methods as
12/// [`alloy_network::TransactionBuilder4844`] for handling blob transaction sidecars, and
13/// [`alloy_network::TransactionBuilder7702`] for handling EIP-7702 authorization lists.
14///
15/// By default, all methods have no-op implementations, so this can be implemented for any Network.
16///
17/// If the Network supports Eip4844 blob transactions implement these methods:
18/// - [`FoundryTransactionBuilder::max_fee_per_blob_gas`]
19/// - [`FoundryTransactionBuilder::set_max_fee_per_blob_gas`]
20/// - [`FoundryTransactionBuilder::blob_versioned_hashes`]
21/// - [`FoundryTransactionBuilder::set_blob_versioned_hashes`]
22/// - [`FoundryTransactionBuilder::blob_sidecar`]
23/// - [`FoundryTransactionBuilder::set_blob_sidecar`]
24///
25/// If the Network supports EIP-7702 authorization lists, implement these methods:
26/// - [`FoundryTransactionBuilder::authorization_list`]
27/// - [`FoundryTransactionBuilder::set_authorization_list`]
28///
29/// If the Network supports Tempo transactions, implement these methods:
30/// - [`FoundryTransactionBuilder::set_fee_token`]
31/// - [`FoundryTransactionBuilder::set_nonce_key`]
32pub trait FoundryTransactionBuilder<N: Network>:
33    TransactionBuilder<N> + Default + Sized + Send + Sync + 'static
34{
35    /// Get the max fee per blob gas for the transaction.
36    fn max_fee_per_blob_gas(&self) -> Option<u128> {
37        None
38    }
39
40    /// Set the max fee per blob gas for the transaction.
41    fn set_max_fee_per_blob_gas(&mut self, _max_fee_per_blob_gas: u128) {}
42
43    /// Builder-pattern method for setting max fee per blob gas.
44    fn with_max_fee_per_blob_gas(mut self, max_fee_per_blob_gas: u128) -> Self {
45        self.set_max_fee_per_blob_gas(max_fee_per_blob_gas);
46        self
47    }
48
49    /// Gets the EIP-4844 blob versioned hashes of the transaction.
50    ///
51    /// These may be set independently of the sidecar, e.g. when the sidecar
52    /// has been pruned but the hashes are still needed for `eth_call`.
53    fn blob_versioned_hashes(&self) -> Option<&[B256]> {
54        None
55    }
56
57    /// Sets the EIP-4844 blob versioned hashes of the transaction.
58    fn set_blob_versioned_hashes(&mut self, _hashes: Vec<B256>) {}
59
60    /// Builder-pattern method for setting the EIP-4844 blob versioned hashes.
61    fn with_blob_versioned_hashes(mut self, hashes: Vec<B256>) -> Self {
62        self.set_blob_versioned_hashes(hashes);
63        self
64    }
65
66    /// Gets the blob sidecar (either EIP-4844 or EIP-7594 variant) of the transaction.
67    fn blob_sidecar(&self) -> Option<&BlobTransactionSidecarVariant> {
68        None
69    }
70
71    /// Sets the blob sidecar (either EIP-4844 or EIP-7594 variant) of the transaction.
72    ///
73    /// Note: This will also set the versioned blob hashes accordingly:
74    /// [BlobTransactionSidecarVariant::versioned_hashes]
75    fn set_blob_sidecar(&mut self, _sidecar: BlobTransactionSidecarVariant) {}
76
77    /// Builder-pattern method for setting the blob sidecar of the transaction.
78    fn with_blob_sidecar(mut self, sidecar: BlobTransactionSidecarVariant) -> Self {
79        self.set_blob_sidecar(sidecar);
80        self
81    }
82
83    /// Gets the EIP-4844 blob sidecar if the current sidecar is of that variant.
84    fn blob_sidecar_4844(&self) -> Option<&BlobTransactionSidecar> {
85        self.blob_sidecar().and_then(|s| s.as_eip4844())
86    }
87
88    /// Sets the EIP-4844 blob sidecar of the transaction.
89    fn set_blob_sidecar_4844(&mut self, sidecar: BlobTransactionSidecar) {
90        self.set_blob_sidecar(BlobTransactionSidecarVariant::Eip4844(sidecar));
91    }
92
93    /// Builder-pattern method for setting the EIP-4844 blob sidecar of the transaction.
94    fn with_blob_sidecar_4844(mut self, sidecar: BlobTransactionSidecar) -> Self {
95        self.set_blob_sidecar_4844(sidecar);
96        self
97    }
98
99    /// Gets the EIP-7594 blob sidecar if the current sidecar is of that variant.
100    fn blob_sidecar_7594(&self) -> Option<&BlobTransactionSidecarEip7594> {
101        self.blob_sidecar().and_then(|s| s.as_eip7594())
102    }
103
104    /// Sets the EIP-7594 blob sidecar of the transaction.
105    fn set_blob_sidecar_7594(&mut self, sidecar: BlobTransactionSidecarEip7594) {
106        self.set_blob_sidecar(BlobTransactionSidecarVariant::Eip7594(sidecar));
107    }
108
109    /// Builder-pattern method for setting the EIP-7594 blob sidecar of the transaction.
110    fn with_blob_sidecar_7594(mut self, sidecar: BlobTransactionSidecarEip7594) -> Self {
111        self.set_blob_sidecar_7594(sidecar);
112        self
113    }
114
115    /// Get the EIP-7702 authorization list for the transaction.
116    fn authorization_list(&self) -> Option<&Vec<SignedAuthorization>> {
117        None
118    }
119
120    /// Sets the EIP-7702 authorization list.
121    fn set_authorization_list(&mut self, _authorization_list: Vec<SignedAuthorization>) {}
122
123    /// Builder-pattern method for setting the authorization list.
124    fn with_authorization_list(mut self, authorization_list: Vec<SignedAuthorization>) -> Self {
125        self.set_authorization_list(authorization_list);
126        self
127    }
128
129    /// Set the fee token for a Tempo transaction.
130    fn set_fee_token(&mut self, _fee_token: Address) {}
131
132    /// Builder-pattern method for setting the Tempo fee token.
133    fn with_fee_token(mut self, fee_token: Address) -> Self {
134        self.set_fee_token(fee_token);
135        self
136    }
137
138    /// Set the 2D nonce key for the Tempo transaction.
139    fn set_nonce_key(&mut self, _nonce_key: U256) {}
140
141    /// Builder-pattern method for setting a 2D nonce key for a Tempo transaction.
142    fn with_nonce_key(mut self, nonce_key: U256) -> Self {
143        self.set_nonce_key(nonce_key);
144        self
145    }
146}
147
148impl FoundryTransactionBuilder<AnyNetwork> for <AnyNetwork as Network>::TransactionRequest {
149    fn max_fee_per_blob_gas(&self) -> Option<u128> {
150        self.max_fee_per_blob_gas
151    }
152
153    fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128) {
154        self.max_fee_per_blob_gas = Some(max_fee_per_blob_gas);
155    }
156
157    fn blob_versioned_hashes(&self) -> Option<&[B256]> {
158        self.blob_versioned_hashes.as_deref()
159    }
160
161    fn set_blob_versioned_hashes(&mut self, hashes: Vec<B256>) {
162        self.blob_versioned_hashes = Some(hashes);
163    }
164
165    fn blob_sidecar(&self) -> Option<&BlobTransactionSidecarVariant> {
166        self.sidecar.as_ref()
167    }
168
169    fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecarVariant) {
170        self.sidecar = Some(sidecar);
171        self.populate_blob_hashes();
172    }
173
174    fn authorization_list(&self) -> Option<&Vec<SignedAuthorization>> {
175        self.authorization_list.as_ref()
176    }
177
178    fn set_authorization_list(&mut self, authorization_list: Vec<SignedAuthorization>) {
179        self.authorization_list = Some(authorization_list);
180    }
181}
182
183impl FoundryTransactionBuilder<TempoNetwork> for <TempoNetwork as Network>::TransactionRequest {
184    fn authorization_list(&self) -> Option<&Vec<SignedAuthorization>> {
185        self.authorization_list.as_ref()
186    }
187
188    fn set_authorization_list(&mut self, authorization_list: Vec<SignedAuthorization>) {
189        self.authorization_list = Some(authorization_list);
190    }
191
192    fn set_fee_token(&mut self, fee_token: Address) {
193        self.fee_token = Some(fee_token);
194    }
195
196    fn set_nonce_key(&mut self, nonce_key: U256) {
197        self.nonce_key = Some(nonce_key);
198    }
199}