Skip to content

Commit f141a43

Browse files
authored
feat: transaction access list option (#8818)
* add access list * fix lint * improve * set access list even if legacy is true * update grammar * update comment to doc string * call access list if no string provided * address comments * update docs * update docs again * address comments * refactor
1 parent 280aa26 commit f141a43

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

crates/cast/bin/tx.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@ use alloy_network::{AnyNetwork, TransactionBuilder};
44
use alloy_primitives::{hex, Address, Bytes, TxKind, U256};
55
use alloy_provider::Provider;
66
use alloy_rlp::Decodable;
7-
use alloy_rpc_types::{Authorization, TransactionInput, TransactionRequest};
7+
use alloy_rpc_types::{AccessList, Authorization, TransactionInput, TransactionRequest};
88
use alloy_serde::WithOtherFields;
99
use alloy_signer::Signer;
1010
use alloy_transport::Transport;
1111
use cast::revm::primitives::SignedAuthorization;
12-
use eyre::Result;
12+
use eyre::{Result, WrapErr};
1313
use foundry_cli::{
1414
opts::TransactionOpts,
1515
utils::{self, parse_function_args},
1616
};
1717
use foundry_common::ens::NameOrAddress;
1818
use foundry_config::{Chain, Config};
1919
use foundry_wallets::{WalletOpts, WalletSigner};
20+
use serde_json;
2021

2122
/// Different sender kinds used by [`CastTxBuilder`].
2223
pub enum SenderKind<'a> {
@@ -134,6 +135,7 @@ pub struct CastTxBuilder<T, P, S> {
134135
auth: Option<String>,
135136
chain: Chain,
136137
etherscan_api_key: Option<String>,
138+
access_list: Option<Option<String>>,
137139
state: S,
138140
_t: std::marker::PhantomData<T>,
139141
}
@@ -190,6 +192,7 @@ where
190192
chain,
191193
etherscan_api_key,
192194
auth: tx_opts.auth,
195+
access_list: tx_opts.access_list,
193196
state: InitState,
194197
_t: std::marker::PhantomData,
195198
})
@@ -206,6 +209,7 @@ where
206209
chain: self.chain,
207210
etherscan_api_key: self.etherscan_api_key,
208211
auth: self.auth,
212+
access_list: self.access_list,
209213
state: ToState { to },
210214
_t: self._t,
211215
})
@@ -266,6 +270,7 @@ where
266270
chain: self.chain,
267271
etherscan_api_key: self.etherscan_api_key,
268272
auth: self.auth,
273+
access_list: self.access_list,
269274
state: InputState { kind: self.state.to.into(), input, func },
270275
_t: self._t,
271276
})
@@ -316,6 +321,20 @@ where
316321
return Ok((self.tx, self.state.func));
317322
}
318323

324+
if let Some(access_list) = match self.access_list {
325+
None => None,
326+
// --access-list provided with no value, call the provider to create it
327+
Some(None) => Some(self.provider.create_access_list(&self.tx).await?.access_list),
328+
// Access list provided as a string, attempt to parse it
329+
Some(Some(ref s)) => Some(
330+
serde_json::from_str::<AccessList>(s)
331+
.map(AccessList::from)
332+
.wrap_err("Failed to parse access list from string")?,
333+
),
334+
} {
335+
self.tx.set_access_list(access_list);
336+
}
337+
319338
if self.legacy && self.tx.gas_price.is_none() {
320339
self.tx.gas_price = Some(self.provider.get_gas_price().await?);
321340
}

crates/cli/src/opts/transaction.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ pub struct TransactionOpts {
6262
/// Can be either a hex-encoded signed authorization or an address.
6363
#[arg(long, conflicts_with_all = &["legacy", "blob"])]
6464
pub auth: Option<String>,
65+
66+
/// EIP-2930 access list.
67+
///
68+
/// Accepts either a JSON-encoded access list or an empty value to create the access list
69+
/// via an RPC call to `eth_createAccessList`. To retrieve only the access list portion, use
70+
/// the `cast access-list` command.
71+
#[arg(long)]
72+
pub access_list: Option<Option<String>>,
6573
}
6674

6775
#[cfg(test)]

0 commit comments

Comments
 (0)