Skip to content

EOA Production Readiness #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions aa-core/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl<C: Chain + Clone> SmartAccountSigner<C> {
},
message,
format,
self.credentials.clone(),
&self.credentials,
)
.await
}
Expand Down Expand Up @@ -189,7 +189,7 @@ impl<C: Chain + Clone> SmartAccountSigner<C> {
from: self.options.signer_address,
},
typed_data,
self.credentials.clone(),
&self.credentials,
)
.await;
}
Expand All @@ -212,7 +212,7 @@ impl<C: Chain + Clone> SmartAccountSigner<C> {
from: self.options.signer_address,
},
typed_data,
self.credentials.clone(),
&self.credentials,
)
.await
}
Expand Down Expand Up @@ -242,7 +242,7 @@ impl<C: Chain + Clone> SmartAccountSigner<C> {
from: self.options.signer_address,
},
&typed_data,
self.credentials.clone(),
&self.credentials,
)
.await
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/execution_options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ pub struct WebhookOptions {
pub struct SendTransactionRequest {
pub execution_options: ExecutionOptions,
pub params: Vec<InnerTransaction>,
pub webhook_options: Option<Vec<WebhookOptions>>,
#[serde(default)]
pub webhook_options: Vec<WebhookOptions>,
}

/// # QueuedTransaction
Expand Down
37 changes: 16 additions & 21 deletions core/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,23 @@ pub trait AccountSigner {
options: Self::SigningOptions,
message: &str,
format: MessageFormat,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> impl std::future::Future<Output = Result<String, EngineError>> + Send;

/// Sign typed data
fn sign_typed_data(
&self,
options: Self::SigningOptions,
typed_data: &TypedData,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> impl std::future::Future<Output = Result<String, EngineError>> + Send;

/// Sign a transaction
fn sign_transaction(
&self,
options: Self::SigningOptions,
transaction: TypedTransaction,
credentials: SigningCredential,
transaction: &TypedTransaction,
credentials: &SigningCredential,
) -> impl std::future::Future<Output = Result<String, EngineError>> + Send;

/// Sign EIP-7702 authorization
Expand All @@ -195,7 +195,7 @@ pub trait AccountSigner {
chain_id: u64,
address: Address,
nonce: alloy::primitives::U256,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> impl std::future::Future<Output = Result<SignedAuthorization, EngineError>> + Send;
}

Expand Down Expand Up @@ -224,7 +224,7 @@ impl AccountSigner for EoaSigner {
options: EoaSigningOptions,
message: &str,
format: MessageFormat,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> Result<String, EngineError> {
match credentials {
SigningCredential::Vault(auth_method) => {
Expand Down Expand Up @@ -260,7 +260,7 @@ impl AccountSigner for EoaSigner {
.sign_message(
auth_token,
thirdweb_auth,
message.to_string(),
message,
options.from,
options.chain_id,
Some(iaw_format),
Expand All @@ -280,7 +280,7 @@ impl AccountSigner for EoaSigner {
&self,
options: EoaSigningOptions,
typed_data: &TypedData,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> Result<String, EngineError> {
match &credentials {
SigningCredential::Vault(auth_method) => {
Expand All @@ -301,12 +301,7 @@ impl AccountSigner for EoaSigner {
} => {
let iaw_result = self
.iaw_client
.sign_typed_data(
auth_token.clone(),
thirdweb_auth.clone(),
typed_data.clone(),
options.from,
)
.sign_typed_data(auth_token, thirdweb_auth, typed_data, options.from)
.await
.map_err(|e| {
tracing::error!("Error signing typed data with EOA (IAW): {:?}", e);
Expand All @@ -321,14 +316,14 @@ impl AccountSigner for EoaSigner {
async fn sign_transaction(
&self,
options: EoaSigningOptions,
transaction: TypedTransaction,
credentials: SigningCredential,
transaction: &TypedTransaction,
credentials: &SigningCredential,
) -> Result<String, EngineError> {
match credentials {
SigningCredential::Vault(auth_method) => {
let vault_result = self
.vault_client
.sign_transaction(auth_method.clone(), transaction, options.from)
.sign_transaction(auth_method.clone(), transaction.clone(), options.from)
.await
.map_err(|e| {
tracing::error!("Error signing transaction with EOA (Vault): {:?}", e);
Expand All @@ -343,7 +338,7 @@ impl AccountSigner for EoaSigner {
} => {
let iaw_result = self
.iaw_client
.sign_transaction(auth_token.clone(), thirdweb_auth.clone(), transaction)
.sign_transaction(auth_token, thirdweb_auth, &transaction)
.await
.map_err(|e| {
tracing::error!("Error signing transaction with EOA (IAW): {:?}", e);
Expand All @@ -361,7 +356,7 @@ impl AccountSigner for EoaSigner {
chain_id: u64,
address: Address,
nonce: U256,
credentials: SigningCredential,
credentials: &SigningCredential,
) -> Result<SignedAuthorization, EngineError> {
// Create the Authorization struct that both clients expect
let authorization = Authorization {
Expand All @@ -373,7 +368,7 @@ impl AccountSigner for EoaSigner {
SigningCredential::Vault(auth_method) => {
let vault_result = self
.vault_client
.sign_authorization(auth_method, options.from, authorization)
.sign_authorization(auth_method.clone(), options.from, authorization)
.await
.map_err(|e| {
tracing::error!("Error signing authorization with EOA (Vault): {:?}", e);
Expand All @@ -389,7 +384,7 @@ impl AccountSigner for EoaSigner {
} => {
let iaw_result = self
.iaw_client
.sign_authorization(auth_token, thirdweb_auth, options.from, authorization)
.sign_authorization(auth_token, thirdweb_auth, options.from, &authorization)
.await
.map_err(|e| {
tracing::error!("Error signing authorization with EOA (IAW): {:?}", e);
Expand Down
10 changes: 8 additions & 2 deletions core/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct InnerTransaction {
/// Gas limit for the transaction
/// If not provided, engine will estimate the gas limit
#[schema(value_type = Option<u64>)]
#[serde(default, rename = "gasLimit")]
#[serde(default, rename = "gasLimit", skip_serializing_if = "Option::is_none")]
pub gas_limit: Option<u64>,

/// Transaction type-specific data for different EIP standards
Expand All @@ -33,7 +33,7 @@ pub struct InnerTransaction {
/// Depending on the execution mode chosen, these might be ignored:
///
/// - For ERC4337 execution, all gas fee related fields are ignored. Sending signed authorizations is also not supported.
#[serde(flatten)]
#[serde(flatten, default, skip_serializing_if = "Option::is_none")]
pub transaction_type_data: Option<TransactionTypeData>,
}

Expand All @@ -58,14 +58,17 @@ pub struct Transaction7702Data {
/// List of signed authorizations for contract delegation
/// Each authorization allows the EOA to temporarily delegate to a smart contract
#[schema(value_type = Option<Vec<SignedAuthorizationSchema>>)]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authorization_list: Option<Vec<SignedAuthorization>>,

/// Maximum fee per gas willing to pay (in wei)
/// This is the total fee cap including base fee and priority fee
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_fee_per_gas: Option<u128>,

/// Maximum priority fee per gas willing to pay (in wei)
/// This is the tip paid to validators for transaction inclusion
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_priority_fee_per_gas: Option<u128>,
}

Expand All @@ -77,10 +80,12 @@ pub struct Transaction7702Data {
pub struct Transaction1559Data {
/// Maximum fee per gas willing to pay (in wei)
/// This is the total fee cap including base fee and priority fee
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_fee_per_gas: Option<u128>,

/// Maximum priority fee per gas willing to pay (in wei)
/// This is the tip paid to validators for transaction inclusion
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_priority_fee_per_gas: Option<u128>,
}

Expand All @@ -92,5 +97,6 @@ pub struct Transaction1559Data {
pub struct TransactionLegacyData {
/// Gas price willing to pay (in wei)
/// This is the total price per unit of gas for legacy transactions
#[serde(default, skip_serializing_if = "Option::is_none")]
pub gas_price: Option<u128>,
}
1 change: 1 addition & 0 deletions executors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition = "2024"
[dependencies]
hex = "0.4.3"
alloy = { version = "1.0.8", features = ["serde"] }
thirdweb-core = { version = "0.1.0", path = "../thirdweb-core" }
hmac = "0.12.1"
reqwest = "0.12.15"
serde = "1.0.219"
Expand Down
5 changes: 3 additions & 2 deletions executors/src/eip7702_executor/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ pub struct Eip7702ConfirmationJobData {
pub bundler_transaction_id: String,
pub eoa_address: Address,
pub rpc_credentials: RpcCredentials,
pub webhook_options: Option<Vec<WebhookOptions>>,
#[serde(default)]
pub webhook_options: Vec<WebhookOptions>,
}

impl HasWebhookOptions for Eip7702ConfirmationJobData {
fn webhook_options(&self) -> Option<Vec<WebhookOptions>> {
fn webhook_options(&self) -> Vec<WebhookOptions> {
self.webhook_options.clone()
}
}
Expand Down
9 changes: 5 additions & 4 deletions executors/src/eip7702_executor/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ pub struct Eip7702SendJobData {
pub transactions: Vec<InnerTransaction>,
pub eoa_address: Address,
pub signing_credential: SigningCredential,
pub webhook_options: Option<Vec<WebhookOptions>>,
#[serde(default)]
pub webhook_options: Vec<WebhookOptions>,
pub rpc_credentials: RpcCredentials,
pub nonce: Option<U256>,
}

impl HasWebhookOptions for Eip7702SendJobData {
fn webhook_options(&self) -> Option<Vec<WebhookOptions>> {
fn webhook_options(&self) -> Vec<WebhookOptions> {
self.webhook_options.clone()
}
}
Expand Down Expand Up @@ -243,7 +244,7 @@ where
.sign_typed_data(
signing_options.clone(),
&typed_data,
job_data.signing_credential.clone(),
&job_data.signing_credential,
)
.await
.map_err(|e| Eip7702SendError::SigningError {
Expand Down Expand Up @@ -272,7 +273,7 @@ where
job_data.chain_id,
MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS,
nonce,
job_data.signing_credential.clone(),
&job_data.signing_credential,
)
.await
.map_err(|e| Eip7702SendError::SigningError {
Expand Down
Loading
Loading