Skip to main content

flashbots_sdk/
tool.rs

1use ethers::{
2    core::rand,
3    signers::{LocalWallet, MnemonicBuilder, coins_bip39::English},
4    types::{H256, transaction::eip2718::TypedTransaction},
5    utils::{self, rlp},
6};
7
8/// Creates a wallet from a private key string
9///
10/// # Example
11/// ```
12/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
13/// let private_key = "4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d";
14/// let wallet = create_wallet_from_private_key(private_key)?;
15/// # Ok(())
16/// # }
17/// ```
18pub fn create_wallet_from_private_key(
19    private_key: &str,
20) -> Result<LocalWallet, Box<dyn std::error::Error>> {
21    let wallet = private_key.parse::<LocalWallet>()?;
22    Ok(wallet)
23}
24
25/// Creates a new random wallet
26pub fn create_random_wallet() -> LocalWallet {
27    LocalWallet::new(&mut rand::thread_rng())
28}
29
30/// Creates a wallet from a mnemonic phrase
31///
32/// # Example
33/// ```
34/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
35/// let mnemonic = "test test test test test test test test test test test junk";
36/// let wallet = create_wallet_from_mnemonic(mnemonic, Some("m/44'/60'/0'/0/0"))?;
37/// # Ok(())
38/// # }
39/// ```
40pub fn create_wallet_from_mnemonic(
41    mnemonic: &str,
42    derivation_path: Option<&str>,
43) -> Result<LocalWallet, Box<dyn std::error::Error>> {
44    let path = derivation_path.unwrap_or("m/44'/60'/0'/0/0");
45    let wallet = MnemonicBuilder::<English>::default()
46        .phrase(mnemonic)
47        .derivation_path(path)?
48        .build()?;
49    Ok(wallet)
50}
51
52/// Validates the format of a signed transaction
53pub fn validate_signed_transaction(tx_hex: &str) -> Result<(), Box<dyn std::error::Error>> {
54    if !tx_hex.starts_with("0x") {
55        return Err("Transaction must start with 0x".into());
56    }
57    let tx_bytes = hex::decode(&tx_hex[2..])?;
58
59    if tx_bytes.len() < 1 {
60        return Err("Transaction data too short".into());
61    }
62    Ok(())
63}
64
65/// Calculates transaction hash from signed transaction hex
66///
67/// # Example
68/// ```
69/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
70/// let tx_hex = "0x02f86b0180843b9aca00852ecc889a0082520894f39fd6e51aad88f6f4ce6ab8827279cfffb92266880de0b6b3a764000080c080a0f67141f7b16b0b61d1ce4f5c5c6b7b7d7e51a7c5e5b5a5a5a5a5a5a5a5a5a5a5a5a0a05a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a";
71/// let hash = TransactionValidator::calculate_transaction_hash(tx_hex)?;
72/// println!("Transaction hash: {:?}", hash);
73/// # Ok(())
74/// # }
75/// ```
76pub fn calculate_transaction_hash(tx_hex: &str) -> Result<H256, Box<dyn std::error::Error>> {
77    let tx_bytes = hex::decode(&tx_hex[2..])?;
78    let hash = utils::keccak256(tx_bytes);
79    Ok(H256::from_slice(&hash))
80}
81
82/// Decodes a signed transaction back to its typed form
83pub fn decode_transaction(tx_hex: &str) -> Result<TypedTransaction, Box<dyn std::error::Error>> {
84    let tx_bytes = hex::decode(&tx_hex[2..])?;
85    let rlp = rlp::Rlp::new(&tx_bytes);
86    let (tx, _signature) = TypedTransaction::decode_signed(&rlp)?;
87    Ok(tx)
88}