|
| 1 | +use crate::defs::AddressDef; |
| 2 | +use alloy::eips::eip7702::SignedAuthorization; |
| 3 | +use alloy::primitives::{Address, U256}; |
| 4 | +use schemars::JsonSchema; |
| 5 | +use serde::{Deserialize, Serialize}; |
| 6 | + |
| 7 | +/// ### EOA Execution Options |
| 8 | +/// This struct configures EOA (Externally Owned Account) direct execution. |
| 9 | +/// |
| 10 | +/// EOA execution sends transactions directly from an EOA address without |
| 11 | +/// smart contract abstraction. This is the most basic form of transaction |
| 12 | +/// execution and is suitable for simple transfers and contract interactions. |
| 13 | +/// |
| 14 | +/// ### Use Cases |
| 15 | +/// - Direct ETH transfers |
| 16 | +/// - Simple contract interactions |
| 17 | +/// - Gas-efficient transactions |
| 18 | +/// - When smart account features are not needed |
| 19 | +/// |
| 20 | +/// ### Features |
| 21 | +/// - Direct transaction execution from EOA |
| 22 | +/// - Automatic nonce management |
| 23 | +/// - Gas price optimization |
| 24 | +/// - Transaction confirmation tracking |
| 25 | +/// - Retry and recovery mechanisms |
| 26 | +/// - Support for EIP-1559, EIP-2930, and Legacy transactions |
| 27 | +/// - Support for EIP-7702 delegated transactions |
| 28 | +#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 29 | +#[serde(rename_all = "camelCase")] |
| 30 | +pub struct EoaExecutionOptions { |
| 31 | + /// The EOA address to send transactions from |
| 32 | + /// This account must have sufficient balance to pay for gas and transaction value |
| 33 | + #[schemars(with = "AddressDef")] |
| 34 | + #[schema(value_type = AddressDef)] |
| 35 | + pub from: Address, |
| 36 | + |
| 37 | + /// The gas limit to use for the transaction |
| 38 | + /// If not provided, the system will auto-detect the best gas limit |
| 39 | + #[schemars(with = "Option<u64>")] |
| 40 | + #[schema(value_type = Option<u64>)] |
| 41 | + pub gas_limit: Option<u64>, |
| 42 | + |
| 43 | + // /// Maximum number of in-flight transactions for this EOA |
| 44 | + // /// Controls how many transactions can be pending confirmation at once |
| 45 | + // /// Defaults to 100 if not specified |
| 46 | + // #[serde(default = "default_max_inflight")] |
| 47 | + // pub max_inflight: u64, |
| 48 | + |
| 49 | + // /// Maximum number of recycled nonces to keep |
| 50 | + // /// When transactions fail, their nonces are recycled for reuse |
| 51 | + // /// Defaults to 50 if not specified |
| 52 | + // #[serde(default = "default_max_recycled_nonces")] |
| 53 | + // pub max_recycled_nonces: u64, |
| 54 | + /// Transaction type-specific data for gas configuration |
| 55 | + /// If not provided, the system will auto-detect the best transaction type |
| 56 | + #[serde(flatten)] |
| 57 | + pub transaction_type_data: Option<EoaTransactionTypeData>, |
| 58 | +} |
| 59 | + |
| 60 | +/// EOA Transaction type-specific data for different EIP standards |
| 61 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 62 | +#[serde(untagged)] |
| 63 | +pub enum EoaTransactionTypeData { |
| 64 | + /// EIP-7702 transaction with authorization list and EIP-1559 gas pricing |
| 65 | + Eip7702(EoaSend7702JobData), |
| 66 | + /// EIP-1559 transaction with priority fee and max fee per gas |
| 67 | + Eip1559(EoaSend1559JobData), |
| 68 | + /// Legacy transaction with simple gas price |
| 69 | + Legacy(EoaSendLegacyJobData), |
| 70 | +} |
| 71 | + |
| 72 | +/// EIP-7702 transaction configuration |
| 73 | +/// Allows delegation of EOA to smart contract logic temporarily |
| 74 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 75 | +#[serde(rename_all = "camelCase")] |
| 76 | +pub struct EoaSend7702JobData { |
| 77 | + /// List of signed authorizations for contract delegation |
| 78 | + /// Each authorization allows the EOA to temporarily delegate to a smart contract |
| 79 | + #[schemars(with = "Option<Vec<SignedAuthorizationSchema>>")] |
| 80 | + #[schema(value_type = Option<Vec<SignedAuthorizationSchema>>)] |
| 81 | + pub authorization_list: Option<Vec<SignedAuthorization>>, |
| 82 | + |
| 83 | + /// Maximum fee per gas willing to pay (in wei) |
| 84 | + /// This is the total fee cap including base fee and priority fee |
| 85 | + pub max_fee_per_gas: Option<u128>, |
| 86 | + |
| 87 | + /// Maximum priority fee per gas willing to pay (in wei) |
| 88 | + /// This is the tip paid to validators for transaction inclusion |
| 89 | + pub max_priority_fee_per_gas: Option<u128>, |
| 90 | +} |
| 91 | + |
| 92 | +/// EIP-1559 transaction configuration |
| 93 | +/// Uses base fee + priority fee model for more predictable gas pricing |
| 94 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 95 | +#[serde(rename_all = "camelCase")] |
| 96 | +pub struct EoaSend1559JobData { |
| 97 | + /// Maximum fee per gas willing to pay (in wei) |
| 98 | + /// This is the total fee cap including base fee and priority fee |
| 99 | + pub max_fee_per_gas: Option<u128>, |
| 100 | + |
| 101 | + /// Maximum priority fee per gas willing to pay (in wei) |
| 102 | + /// This is the tip paid to validators for transaction inclusion |
| 103 | + pub max_priority_fee_per_gas: Option<u128>, |
| 104 | +} |
| 105 | + |
| 106 | +/// Legacy transaction configuration |
| 107 | +/// Uses simple gas price model (pre-EIP-1559) |
| 108 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 109 | +#[serde(rename_all = "camelCase")] |
| 110 | +pub struct EoaSendLegacyJobData { |
| 111 | + /// Gas price willing to pay (in wei) |
| 112 | + /// This is the total price per unit of gas for legacy transactions |
| 113 | + pub gas_price: Option<u128>, |
| 114 | +} |
| 115 | + |
| 116 | +/// EIP-7702 Authorization structure for OpenAPI schema |
| 117 | +/// Represents an unsigned authorization that allows an EOA to delegate to a smart contract |
| 118 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 119 | +#[serde(rename_all = "camelCase")] |
| 120 | +pub struct AuthorizationSchema { |
| 121 | + /// The chain ID of the authorization |
| 122 | + /// Must match the chain where the transaction will be executed |
| 123 | + #[schemars(with = "String")] |
| 124 | + #[schema(value_type = String, example = "1")] |
| 125 | + pub chain_id: U256, |
| 126 | + |
| 127 | + /// The smart contract address to delegate to |
| 128 | + /// This contract will be able to execute logic on behalf of the EOA |
| 129 | + #[schemars(with = "AddressDef")] |
| 130 | + #[schema(value_type = AddressDef)] |
| 131 | + pub address: Address, |
| 132 | + |
| 133 | + /// The nonce for the authorization |
| 134 | + /// Must be the current nonce of the authorizing account |
| 135 | + #[schema(example = 42)] |
| 136 | + pub nonce: u64, |
| 137 | +} |
| 138 | + |
| 139 | +/// EIP-7702 Signed Authorization structure for OpenAPI schema |
| 140 | +/// Contains an authorization plus the cryptographic signature |
| 141 | +#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, utoipa::ToSchema)] |
| 142 | +#[serde(rename_all = "camelCase")] |
| 143 | +pub struct SignedAuthorizationSchema { |
| 144 | + /// The chain ID of the authorization |
| 145 | + /// Must match the chain where the transaction will be executed |
| 146 | + #[schemars(with = "String")] |
| 147 | + #[schema(value_type = String, example = "1")] |
| 148 | + pub chain_id: U256, |
| 149 | + |
| 150 | + /// The smart contract address to delegate to |
| 151 | + /// This contract will be able to execute logic on behalf of the EOA |
| 152 | + #[schemars(with = "AddressDef")] |
| 153 | + #[schema(value_type = AddressDef)] |
| 154 | + pub address: Address, |
| 155 | + |
| 156 | + /// The nonce for the authorization |
| 157 | + /// Must be the current nonce of the authorizing account |
| 158 | + #[schema(example = 42)] |
| 159 | + pub nonce: u64, |
| 160 | + |
| 161 | + /// Signature parity value (0 or 1) |
| 162 | + /// Used for ECDSA signature recovery |
| 163 | + #[serde(rename = "yParity", alias = "v")] |
| 164 | + #[schema(example = 0)] |
| 165 | + pub y_parity: u8, |
| 166 | + |
| 167 | + /// Signature r value |
| 168 | + /// First component of the ECDSA signature |
| 169 | + #[schemars(with = "String")] |
| 170 | + #[schema(value_type = String, example = "0x1234567890abcdef...")] |
| 171 | + pub r: U256, |
| 172 | + |
| 173 | + /// Signature s value |
| 174 | + /// Second component of the ECDSA signature |
| 175 | + #[schemars(with = "String")] |
| 176 | + #[schema(value_type = String, example = "0xfedcba0987654321...")] |
| 177 | + pub s: U256, |
| 178 | +} |
| 179 | + |
| 180 | +fn default_max_inflight() -> u64 { |
| 181 | + 100 |
| 182 | +} |
| 183 | + |
| 184 | +fn default_max_recycled_nonces() -> u64 { |
| 185 | + 50 |
| 186 | +} |
0 commit comments