Skip to content
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
2 changes: 1 addition & 1 deletion aa-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod userop;

pub use userop::*;
pub use userop::*;
7 changes: 5 additions & 2 deletions core/src/rpc_clients/bundler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,11 @@ impl BundlerClient {
Ok(response)
}

pub async fn tw_get_delegation_contract(&self) -> TransportResult<TwGetDelegationContractResponse> {
let response: TwGetDelegationContractResponse = self.inner.request("tw_getDelegationContract", ()).await?;
pub async fn tw_get_delegation_contract(
&self,
) -> TransportResult<TwGetDelegationContractResponse> {
let response: TwGetDelegationContractResponse =
self.inner.request("tw_getDelegationContract", ()).await?;
Ok(response)
}
}
2 changes: 1 addition & 1 deletion core/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ impl SolanaSigner {
solana_sdk::signature::Signature::default(),
);
};

transaction.signatures[signer_index] = signature;

Ok(transaction)
Expand Down
2 changes: 1 addition & 1 deletion eip7702-core/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
pub const EIP_7702_DELEGATION_PREFIX: [u8; 3] = [0xef, 0x01, 0x00];

/// EIP-7702 delegation code length (prefix + address)
pub const EIP_7702_DELEGATION_CODE_LENGTH: usize = 23;
pub const EIP_7702_DELEGATION_CODE_LENGTH: usize = 23;
13 changes: 6 additions & 7 deletions eip7702-core/src/delegated_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ impl<C: Chain> DelegatedAccount<C> {
}

/// Check if the EOA has EIP-7702 delegation to the minimal account implementation
pub async fn is_minimal_account(&self, delegation_contract: Option<Address>) -> Result<bool, EngineError> {
pub async fn is_minimal_account(
&self,
delegation_contract: Option<Address>,
) -> Result<bool, EngineError> {
// Get the bytecode at the EOA address using eth_getCode
let code = self
.chain
Expand Down Expand Up @@ -65,12 +68,8 @@ impl<C: Chain> DelegatedAccount<C> {

// Compare with the minimal account implementation address
let is_delegated = match delegation_contract {
Some(delegation_contract) => {
target_address == delegation_contract
}
None => {
true
}
Some(delegation_contract) => target_address == delegation_contract,
None => true,
};

tracing::debug!(
Expand Down
2 changes: 1 addition & 1 deletion eip7702-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod constants;
pub mod delegated_account;
pub mod transaction;
pub mod transaction;
11 changes: 9 additions & 2 deletions eip7702-core/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,18 @@ impl<C: Chain> MinimalAccountTransaction<C> {
credentials: &SigningCredential,
delegation_contract: Address,
) -> Result<Self, EngineError> {
if self.account.is_minimal_account(Some(delegation_contract)).await? {
if self
.account
.is_minimal_account(Some(delegation_contract))
.await?
{
return Ok(self);
}

let authorization = self.account.sign_authorization(signer, credentials, delegation_contract).await?;
let authorization = self
.account
.sign_authorization(signer, credentials, delegation_contract)
.await?;
self.authorization = Some(authorization);
Ok(self)
}
Expand Down
36 changes: 26 additions & 10 deletions eip7702-core/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,9 @@ impl TestSetup {
async fn test_eip7702_integration() -> Result<(), Box<dyn std::error::Error>> {
// Set up test environment
let mut setup = TestSetup::new().await?;
let delegation_contract = setup.delegation_contract.expect("Delegation contract should be set");
let delegation_contract = setup
.delegation_contract
.expect("Delegation contract should be set");

// Step 1: Fetch and set bytecode from Base Sepolia
setup.fetch_and_set_bytecode().await?;
Expand All @@ -667,11 +669,15 @@ async fn test_eip7702_integration() -> Result<(), Box<dyn std::error::Error>> {

// Step 3: Test is_minimal_account - all should be false initially
assert!(
!developer_account.is_minimal_account(Some(delegation_contract)).await?,
!developer_account
.is_minimal_account(Some(delegation_contract))
.await?,
"Developer should not be minimal account initially"
);
assert!(
!user_account.is_minimal_account(Some(delegation_contract)).await?,
!user_account
.is_minimal_account(Some(delegation_contract))
.await?,
"User should not be minimal account initially"
);
println!("✓ All accounts are not minimal accounts initially");
Expand All @@ -696,9 +702,11 @@ async fn test_eip7702_integration() -> Result<(), Box<dyn std::error::Error>> {
.clone()
.owner_transaction(&[mint_transaction])
.add_authorization_if_needed(
&setup.signer,
&setup.signer,
&setup.developer_credentials,
setup.delegation_contract.expect("Delegation contract should be set")
setup
.delegation_contract
.expect("Delegation contract should be set"),
)
.await?;

Expand Down Expand Up @@ -732,17 +740,21 @@ async fn test_eip7702_integration() -> Result<(), Box<dyn std::error::Error>> {
);

assert!(
developer_account.is_minimal_account(Some(delegation_contract)).await?,
developer_account
.is_minimal_account(Some(delegation_contract))
.await?,
"Developer should be minimal account after minting"
);

// Step 8: Delegate user account (session key granter)
// User signs authorization but executor broadcasts it (user has no funds)
let user_authorization = user_account
.sign_authorization(
&setup.signer,
&setup.signer,
&setup.user_credentials,
setup.delegation_contract.expect("Delegation contract should be set")
setup
.delegation_contract
.expect("Delegation contract should be set"),
)
.await?;

Expand All @@ -752,14 +764,18 @@ async fn test_eip7702_integration() -> Result<(), Box<dyn std::error::Error>> {
.await?;

assert!(
user_account.is_minimal_account(Some(delegation_contract)).await?,
user_account
.is_minimal_account(Some(delegation_contract))
.await?,
"User (session key granter) should be minimal account after delegation"
);
println!("✓ User (session key granter) is now a minimal account (delegated by executor)");

// Step 9: Developer is already delegated via add_authorization_if_needed in owner_transaction
assert!(
developer_account.is_minimal_account(Some(delegation_contract)).await?,
developer_account
.is_minimal_account(Some(delegation_contract))
.await?,
"Developer (session key grantee) should already be minimal account from earlier delegation"
);
println!("✓ Developer (session key grantee) was already delegated in previous step");
Expand Down
4 changes: 2 additions & 2 deletions executors/src/eip7702_executor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod send;
pub mod confirm;
pub mod delegation_cache;
pub mod delegation_cache;
pub mod send;
4 changes: 3 additions & 1 deletion executors/src/eoa/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,9 @@ impl EoaExecutorStore {
let mut pending_transactions: Vec<PendingTransaction> = Vec::new();
let mut deletion_pipe = twmq::redis::pipe();

for ((transaction_id, queued_at), user_request) in transaction_ids.into_iter().zip(user_requests) {
for ((transaction_id, queued_at), user_request) in
transaction_ids.into_iter().zip(user_requests)
{
match user_request {
Some(user_request) => {
let user_request_parsed = serde_json::from_str(&user_request)?;
Expand Down
3 changes: 2 additions & 1 deletion executors/src/eoa/worker/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,8 @@ impl<C: Chain> EoaExecutorWorker<C> {
"Found newest transaction for gas bump"
);

let time_since_queuing = EoaExecutorStore::now().saturating_sub(newest_transaction_data.created_at);
let time_since_queuing =
EoaExecutorStore::now().saturating_sub(newest_transaction_data.created_at);

if time_since_queuing < NONCE_STALL_LIMIT_MS {
tracing::warn!(
Expand Down
Loading
Loading