Skip to content

Commit cc97a3b

Browse files
committed
feat(cast mktx): add support for "--ethsign" option
- Sign transactions using "eth_signTransaction" on local node with unlocked accounts. - Same TX building logic as in "cast send --unlocked". - Added a test case to validate the new functionality.
1 parent 5e20961 commit cc97a3b

File tree

2 files changed

+53
-10
lines changed

2 files changed

+53
-10
lines changed

crates/cast/src/cmd/mktx.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::tx::{self, CastTxBuilder};
22
use alloy_ens::NameOrAddress;
33
use alloy_network::{eip2718::Encodable2718, EthereumWallet, TransactionBuilder};
44
use alloy_primitives::hex;
5+
use alloy_provider::Provider;
56
use alloy_signer::Signer;
67
use clap::Parser;
78
use eyre::{OptionExt, Result};
@@ -50,6 +51,10 @@ pub struct MakeTxArgs {
5051
/// Relaxes the wallet requirement.
5152
#[arg(long, requires = "from")]
5253
raw_unsigned: bool,
54+
55+
/// Call `eth_signTransaction` using the `--from` argument or $ETH_FROM as sender
56+
#[arg(long, requires = "from", conflicts_with = "raw_unsigned")]
57+
ethsign: bool,
5358
}
5459

5560
#[derive(Debug, Parser)]
@@ -70,7 +75,7 @@ pub enum MakeTxSubcommands {
7075

7176
impl MakeTxArgs {
7277
pub async fn run(self) -> Result<()> {
73-
let Self { to, mut sig, mut args, command, tx, path, eth, raw_unsigned } = self;
78+
let Self { to, mut sig, mut args, command, tx, path, eth, raw_unsigned, ethsign } = self;
7479

7580
let blob_data = if let Some(path) = path { Some(std::fs::read(path)?) } else { None };
7681

@@ -91,7 +96,7 @@ impl MakeTxArgs {
9196

9297
let provider = get_provider(&config)?;
9398

94-
let tx_builder = CastTxBuilder::new(provider, tx, &config)
99+
let tx_builder = CastTxBuilder::new(&provider, tx, &config)
95100
.await?
96101
.with_to(to)
97102
.await?
@@ -108,19 +113,30 @@ impl MakeTxArgs {
108113
return Ok(());
109114
}
110115

111-
// Retrieve the signer, and bail if it can't be constructed.
112-
let signer = eth.wallet.signer().await?;
113-
let from = signer.address();
116+
// Case 1:
117+
// Use eth_signTransaction to sign the transaction.
118+
if ethsign {
119+
let (tx, _) = tx_builder.build(config.sender).await?;
120+
121+
let signed_tx = provider.sign_transaction(tx).await?;
122+
sh_println!("{signed_tx}")?;
114123

115-
tx::validate_from_address(eth.wallet.from, from)?;
124+
// Case 2:
125+
// local signer
126+
} else {
127+
// get the signer from the wallet, and fail if it can't be constructed.
128+
let signer = eth.wallet.signer().await?;
129+
let from = signer.address();
116130

117-
let (tx, _) = tx_builder.build(&signer).await?;
131+
tx::validate_from_address(eth.wallet.from, from)?;
118132

119-
let tx = tx.build(&EthereumWallet::new(signer)).await?;
133+
let (tx, _) = tx_builder.build(&signer).await?;
120134

121-
let signed_tx = hex::encode(tx.encoded_2718());
122-
sh_println!("0x{signed_tx}")?;
135+
let tx = tx.build(&EthereumWallet::new(signer)).await?;
123136

137+
let signed_tx = hex::encode(tx.encoded_2718());
138+
sh_println!("0x{signed_tx}")?;
139+
}
124140
Ok(())
125141
}
126142
}

crates/cast/tests/cli/main.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,33 @@ casttest!(mktx_raw_unsigned, |_prj, cmd| {
12961296
]]);
12971297
});
12981298

1299+
casttest!(mktx_ethsign, |_prj, cmd| {
1300+
cmd.args([
1301+
"mktx",
1302+
"--from",
1303+
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
1304+
"--chain",
1305+
"31337",
1306+
"--nonce",
1307+
"0",
1308+
"--gas-limit",
1309+
"21000",
1310+
"--gas-price",
1311+
"10000000000",
1312+
"--priority-gas-price",
1313+
"1000000000",
1314+
"0x0000000000000000000000000000000000000001",
1315+
"--ethsign",
1316+
])
1317+
.assert_success()
1318+
.stdout_eq(str![[
1319+
r#"
1320+
0x02f86d827a6980843b9aca008502540be4008252089400000000000000000000000000000000000000018080c001a0b8eeb1ded87b085859c510c5692bed231e3ee8b068ccf71142bbf28da0e95987a07813b676a248ae8055f28495021d78dee6695479d339a6ad9d260d9eaf20674c
1321+
1322+
"#
1323+
]]);
1324+
});
1325+
12991326
// tests that the raw encoded transaction is returned
13001327
casttest!(tx_raw, |_prj, cmd| {
13011328
let rpc = next_http_rpc_endpoint();

0 commit comments

Comments
 (0)