Skip to content

7702 execution session keys #21

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 2 commits into from
Jul 23, 2025
Merged

7702 execution session keys #21

merged 2 commits into from
Jul 23, 2025

Conversation

d4mr
Copy link
Member

@d4mr d4mr commented Jul 22, 2025

Summary by CodeRabbit

  • New Features

    • Introduced support for EIP-7702 delegated accounts, enabling both owner and session key execution modes.
    • Added a new core module for EIP-7702, providing abstractions for delegated accounts, transaction construction, and authorization signing.
    • Enhanced transaction handling to distinguish sender details between owner and session key.
  • Bug Fixes

    • Improved error handling and retry logic for transaction execution and job processing.
  • Refactor

    • Unified and streamlined transaction construction and signing logic for EIP-7702 accounts.
    • Updated job data structures to support new execution options and sender details.
    • Simplified code by leveraging Rust’s derive macros for default values.
  • Chores

    • Updated dependencies and workspace configuration to include the new EIP-7702 core module.

d4mr added 2 commits July 22, 2025 20:05
- Introduced the `engine-eip7702-core` package with its dependencies in `Cargo.lock` and `Cargo.toml`.
- Updated the `executors` module to include `engine-eip7702-core` as a dependency.
- Refactored execution options in `eip7702.rs` to support new execution models for EIP-7702.
- Enhanced transaction handling in the `eip7702_executor` to accommodate new sender details and improve compatibility with existing job structures.
- Updated webhook and job data structures to reflect changes in sender details and execution options.
- Improved error handling and retry logic in job processing to enhance robustness.
Copy link

coderabbitai bot commented Jul 22, 2025

Walkthrough

This update introduces a new eip7702-core crate, encapsulating logic for EIP-7702 delegated accounts and minimal account transactions, and integrates it into the workspace and executors. The EIP-7702 execution option types are refactored as enums for extensibility. Executor job data and result structures are updated for backward compatibility and support for session keys. Error handling and retry logic are enhanced in both the core abstractions and job management.

Changes

Files/Paths Change Summary
Cargo.toml, executors/Cargo.toml Added eip7702-core as a workspace member and as a dependency in executors.
eip7702-core/Cargo.toml New package manifest for engine-eip7702-core with dependencies.
eip7702-core/src/constants.rs Defines EIP-7702 delegation constants (addresses, prefix, code length).
eip7702-core/src/delegated_account.rs Implements DelegatedAccount abstraction with delegation checks, nonce retrieval, authorization signing, and UID generation.
eip7702-core/src/transaction.rs Implements MinimalAccountTransaction for building, signing, and executing minimal account transactions.
eip7702-core/src/lib.rs Exposes new modules: constants, delegated_account, transaction.
core/src/execution_options/eip7702.rs Refactors EIP-7702 execution options from a struct to an enum with Owner and SessionKey variants; updates serialization and documentation.
core/src/execution_options/mod.rs Removes JsonSchema derive from SpecificExecutionOptions enum.
core/src/signer.rs Changes method call to pass transaction by value instead of by reference.
executors/src/eip7702_executor/send.rs, executors/src/eip7702_executor/confirm.rs Refactors job data/result types: eoa_address now optional, adds Eip7702Sender enum, supports session key execution, updates error handling and retry logic, integrates DelegatedAccount.
executors/src/eoa/error_classifier.rs Removes unused import.
server/src/execution_router/mod.rs Updates job data construction for EIP-7702 execution: eoa_address set to None, adds execution_options.
thirdweb-core/src/iaw/mod.rs Derives Default for MessageFormat enum, removes manual implementation.
twmq/src/job.rs Adds error mapping and job error creation methods with max retry logic to ToJobResult and ToJobError traits.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Executor
    participant DelegatedAccount
    participant Bundler

    Client->>Executor: Submit EIP-7702 job (with execution_options)
    Executor->>DelegatedAccount: Construct DelegatedAccount (from options)
    Executor->>DelegatedAccount: Check is_minimal_account()
    DelegatedAccount-->>Executor: Returns delegation status
    Executor->>DelegatedAccount: Build MinimalAccountTransaction (owner/session key)
    Executor->>DelegatedAccount: (If needed) Sign authorization
    DelegatedAccount-->>Executor: Returns signed authorization
    Executor->>MinimalAccountTransaction: Build wrapped calls, sign transaction
    MinimalAccountTransaction-->>Executor: Returns payload and signature
    Executor->>Bundler: Submit transaction for execution
    Bundler-->>Executor: Returns transaction result
    Executor-->>Client: Returns job result (with sender details)
Loading

Estimated code review effort

4 (~90 minutes)

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
thirdweb-core/src/iaw/mod.rs (1)

70-76: Unify #[derive] blocks to avoid duplication

You currently have two consecutive #[derive] attributes:

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Default)]

It’s legal, but redundant and easy to overlook when adding further traits. Consider merging:

-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[derive(Default)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]

Pure style, feel free to ignore if preferred.

eip7702-core/src/constants.rs (1)

3-11: Add a quick unit-test to guard hard-coded delegation constants

Hard-coding the delegation prefix, address and computed length is fine, but a tiny test will prevent accidental edits:

#[test]
fn test_eip7702_constants() {
    use super::*;
    assert_eq!(EIP_7702_DELEGATION_PREFIX.len() + 20, EIP_7702_DELEGATION_CODE_LENGTH);
}

Helps catch mismatches during refactors.

executors/src/eip7702_executor/confirm.rs (1)

34-38: Add tracking information to the migration TODOs.

The backward compatibility approach is good, but the TODOs should include more specific tracking information (e.g., a ticket number, target date, or version) to ensure timely cleanup.

-    /// ! Deprecated todo: remove this field after all jobs are processed
+    /// ! Deprecated: Remove this field after migration is complete (track via issue #XXX)
     pub eoa_address: Option<Address>,

-    // TODO: make non-optional after all jobs are processed
+    // TODO: Make non-optional after migration is complete (track via issue #XXX)
     pub sender_details: Option<Eip7702Sender>,
executors/src/eip7702_executor/send.rs (2)

42-50: Track the backward compatibility TODO in an issue

The TODO comment indicates a temporary backward compatibility solution. This should be tracked in an issue to ensure it's addressed in the next release.

Would you like me to create an issue to track the removal of eoa_address field and making execution_options required in the next release?


259-269: Consider renaming is_build_error_retryable for clarity

The function is_build_error_retryable is used for authorization signing errors, but its name suggests it's specifically for build errors. Consider renaming to is_error_retryable or creating a more specific function for authorization errors.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9cb1163 and 509e657.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • Cargo.toml (1 hunks)
  • core/src/execution_options/eip7702.rs (1 hunks)
  • core/src/execution_options/mod.rs (1 hunks)
  • core/src/signer.rs (1 hunks)
  • eip7702-core/Cargo.toml (1 hunks)
  • eip7702-core/src/constants.rs (1 hunks)
  • eip7702-core/src/delegated_account.rs (1 hunks)
  • eip7702-core/src/lib.rs (1 hunks)
  • eip7702-core/src/transaction.rs (1 hunks)
  • executors/Cargo.toml (1 hunks)
  • executors/src/eip7702_executor/confirm.rs (6 hunks)
  • executors/src/eip7702_executor/send.rs (6 hunks)
  • executors/src/eoa/error_classifier.rs (1 hunks)
  • server/src/execution_router/mod.rs (1 hunks)
  • thirdweb-core/src/iaw/mod.rs (1 hunks)
  • twmq/src/job.rs (3 hunks)
🧬 Code Graph Analysis (1)
twmq/src/job.rs (1)
twmq/src/multilane.rs (1)
  • delay (1342-1348)
🧰 Additional context used
🧬 Code Graph Analysis (1)
twmq/src/job.rs (1)
twmq/src/multilane.rs (1)
  • delay (1342-1348)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: coverage
  • GitHub Check: test
🔇 Additional comments (24)
executors/Cargo.toml (1)

19-19: LGTM! Clean dependency addition for EIP-7702 support.

The addition of the engine-eip7702-core dependency with local path reference is correctly structured and supports the new EIP-7702 functionality.

Cargo.toml (1)

6-6: LGTM! Proper workspace integration.

The addition of "eip7702-core" to the workspace members is correctly placed and necessary for the new crate integration.

executors/src/eoa/error_classifier.rs (1)

245-245: LGTM! Clean import optimization.

Removing the unused ToJobResult import while keeping ToJobError is a good cleanup that aligns with the actual usage in the to_send_job_result method.

server/src/execution_router/mod.rs (1)

353-354: Compatibility with new execution/job structure confirmed

The Eip7702 executor’s Eip7702SendJobData still defines

pub eoa_address: Option<Address>,  // legacy support until next release
pub execution_options: Option<…>,  // new structured options

and in executors/src/eip7702_executor/send.rs it selects the sender via:

  • If eoa_address: Some(addr), it maps to Eip7702Sender::Owner { eoa_address: addr }
  • Otherwise (i.e. eoa_address: None), it reads from execution_options, handling both Owner and SessionKey variants

This preserves backward compatibility for queued jobs created before this change while fully supporting the new model. No further action is required.

core/src/signer.rs (1)

341-341: IAW client signature confirmed – passing transaction (a &TypedTransaction) matches the expected &EthereumTypedTransaction<…> parameter.

No unnecessary moves or clones introduced, and this aligns with the vault client’s use of transaction.clone() (since it requires ownership).

All good to go.

core/src/execution_options/mod.rs (1)

29-47: Confirm removal of JsonSchema derive doesn’t break OpenAPI consumers

SpecificExecutionOptions no longer derives schemars::JsonSchema, while other structs in this module still do.
If any downstream tooling combines utoipa::ToSchema with schemars::JsonSchema (e.g. utoipa-swagger-ui when generating component references), the missing derive could cause schema gaps or runtime panics during OpenAPI generation.

Please double-check the docs/CI that produce OpenAPI specs and, if necessary, keep JsonSchema or add #[cfg_attr(feature = "schema", derive(JsonSchema))] to gate the dependency.

eip7702-core/src/lib.rs (1)

1-3: Module pub re-exports look good

Publicly re-exporting the three sub-modules makes the crate’s API clear and ergonomic.

core/src/execution_options/eip7702.rs (1)

9-36: LGTM! Well-structured enum design for execution options.

The refactoring from a single struct to an enum with Owner and SessionKey variants provides good extensibility. The untagged serialization works well here since the variants have distinct field names, preventing deserialization ambiguity.

twmq/src/job.rs (1)

58-101: LGTM! Useful retry-aware error handling methods.

The new map_err_with_max_retries and nack_with_max_retries methods provide a clean way to conditionally fail jobs after exceeding retry limits. The implementation correctly checks current_attempts >= max_retries to determine whether to fail or requeue.

executors/src/eip7702_executor/confirm.rs (2)

97-97: Good optimization: Boxing large error variant.

Boxing the TransactionReceipt reduces the size of the error enum, which is beneficial for performance when errors are propagated through the call stack.


265-277: LGTM! Well-implemented backward compatibility.

The migration logic correctly handles both the new sender_details field and the deprecated eoa_address field, with appropriate error handling when neither is present.

eip7702-core/src/delegated_account.rs (4)

33-80: LGTM! Correct EIP-7702 delegation verification.

The delegation checking logic correctly:

  • Validates the delegation prefix (0xef0100)
  • Extracts the target address from the correct byte range [3..23]
  • Includes helpful debug logging for troubleshooting

87-94: LGTM! Clean nonce retrieval implementation.

Simple and correct delegation to the chain provider with proper error handling.


101-123: LGTM! Well-structured authorization signing.

The method provides a clean abstraction for EIP-7702 authorization signing, correctly fetching the nonce and setting up the signing context.


125-132: LGTM! Secure random UID generation.

The implementation correctly uses the rand crate's cryptographically secure RNG to generate a 32-byte UID.

eip7702-core/src/transaction.rs (5)

46-95: LGTM! Well-documented session key transaction flow.

The double-wrapping logic correctly implements the session key execution pattern. The detailed comments effectively explain the transaction flow from executor → session key → target account.


97-121: LGTM! Clean owner transaction implementation.

The owner transaction flow is appropriately simpler than the session key flow, directly wrapping the calls without intermediate steps.


129-141: LGTM! Correct conditional authorization logic.

The method correctly adds authorization only when needed (i.e., when the account doesn't already have EIP-7702 delegation set up).


162-181: LGTM! Clean transaction execution flow.

The execute method properly orchestrates building the transaction data and submitting it to the bundler with appropriate error handling.


220-231: LGTM! Proper EIP-712 typed data implementation.

The typed data creation correctly uses the minimal account domain parameters and properly sets the verifying contract to the account address.

executors/src/eip7702_executor/send.rs (4)

86-96: Well-designed sender enum structure

The Eip7702Sender enum provides a clean abstraction for distinguishing between owner and session key transactions, with appropriate serde attributes for flexible serialization.


211-221: Owner address resolution handles backward compatibility correctly

The logic properly resolves the owner address from either the legacy eoa_address field or the new execution_options, with appropriate error handling when both are None.


473-484: Comprehensive revert detection logic

The contains_revert_data function provides thorough detection of contract reverts using both common selectors and revert-related keywords.


459-461: Fix pattern matching for HTTP 500 errors

The pattern match on line 460 is incorrect. It should properly destructure the status code.

-        RpcErrorKind::TransportHttpError { status: 500, body } => !contains_revert_data(body),
+        RpcErrorKind::TransportHttpError { status, body } if *status == 500 => !contains_revert_data(body),

Likely an incorrect or invalid review comment.

Comment on lines +6 to +8
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[schema(title = "EIP-7702 Execution Options")]
#[serde(rename_all = "camelCase", untagged)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the removal of JsonSchema derive is intentional.

The JsonSchema derive was removed from the enum while being retained on the struct variants. This might affect API documentation generation if schemas are used for OpenAPI specs.


🏁 Script executed:

#!/bin/bash
# Description: Check if JsonSchema removal is consistent across execution options

# Check if other execution option enums also removed JsonSchema
rg -A 3 "enum.*ExecutionOptions" --type rust

# Check for any schema-related issues or TODOs
rg -i "schema|openapi" -C 3 "ExecutionOptions" --type rust

Length of output: 890


🏁 Script executed:

#!/bin/bash
set -e
# List all files in the execution_options directory
find core/src/execution_options -maxdepth 1 -type f

# Check for any remaining JsonSchema derives in this directory
rg "#\[derive.*JsonSchema" -n core/src/execution_options

# List all derive macros to see which traits are used
rg "#\[derive" -n core/src/execution_options

# Show the first 20 lines of mod.rs to inspect its derive attributes
sed -n '1,20p' core/src/execution_options/mod.rs

Length of output: 3451


Add missing JsonSchema derive to EIP-7702 execution options

The Eip7702ExecutionOptions enum and its two variant structs currently derive Debug, Clone, Serialize, Deserialize, and utoipa::ToSchema, but omit JsonSchema. All other ExecutionOptions types in this module include the JsonSchema derive to feed Schemars into your OpenAPI docs. To keep schema generation consistent, please update the derives as follows:

• In core/src/execution_options/eip7702.rs:

- #[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
+ #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, utoipa::ToSchema)]

• Apply the same change to the two structs at lines 17 and 26 so they also include JsonSchema.

This will restore Schemars support for the EIP-7702 options and align with the rest of the execution-options API.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
#[schema(title = "EIP-7702 Execution Options")]
#[serde(rename_all = "camelCase", untagged)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, utoipa::ToSchema)]
#[schema(title = "EIP-7702 Execution Options")]
#[serde(rename_all = "camelCase", untagged)]
🤖 Prompt for AI Agents
In core/src/execution_options/eip7702.rs around lines 6 to 8, the
Eip7702ExecutionOptions enum is missing the JsonSchema derive attribute. Add
JsonSchema to the derive list alongside Debug, Clone, Serialize, Deserialize,
and utoipa::ToSchema. Also, locate the two variant structs at lines 17 and 26
and add the JsonSchema derive to them as well to ensure consistent schema
generation across all execution option types.

Comment on lines +1 to +14
[package]
name = "engine-eip7702-core"
version = "0.1.0"
edition = "2024"

[dependencies]
alloy = { workspace = true, features = ["serde"] }
tokio = "1.44.2"
engine-core = { path = "../core" }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0"
tracing = "0.1.41"
rand = "0.9"
thiserror = "2.0"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

edition = "2024" and tokio = "1.44.2" are not yet available

  • edition = "2024" is unstable on the current stable toolchain; compilation will fail for all users not on nightly with the 2024-edition preview enabled.
  • The latest published tokio crate is 1.38.x (as of July 2025). Version 1.44.2 does not exist and will cause cargo resolution errors.
-edition = "2024"
+edition = "2021"

-tokio = "1.44.2"
+# keep in sync with workspace root
+tokio = "1.38"

Please bump once the official 2024 edition and the referenced Tokio release ship.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[package]
name = "engine-eip7702-core"
version = "0.1.0"
edition = "2024"
[dependencies]
alloy = { workspace = true, features = ["serde"] }
tokio = "1.44.2"
engine-core = { path = "../core" }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0"
tracing = "0.1.41"
rand = "0.9"
thiserror = "2.0"
[package]
name = "engine-eip7702-core"
version = "0.1.0"
edition = "2021"
[dependencies]
alloy = { workspace = true, features = ["serde"] }
# keep in sync with workspace root
tokio = "1.38"
engine-core = { path = "../core" }
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0"
tracing = "0.1.41"
rand = "0.9"
thiserror = "2.0"
🤖 Prompt for AI Agents
In eip7702-core/Cargo.toml lines 1 to 14, the edition is set to "2024" which is
not stable and the tokio version "1.44.2" does not exist. Change the edition to
the latest stable one, such as "2021", and set the tokio dependency to the
latest published version, for example "1.38". Update these once the official
2024 edition and the correct Tokio version are released.

@d4mr d4mr merged commit f79dea4 into main Jul 23, 2025
4 of 5 checks passed
@d4mr d4mr deleted the pb/7702-session-key branch July 23, 2025 07:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants