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 build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub fn build(b: *std.Build) void {
"05_transaction_receipts",
"06_event_monitoring",
"07_complete_workflow",
"account_abstraction_example",
"08_account_abstraction",
};

for (example_names) |example_name| {
Expand Down
494 changes: 494 additions & 0 deletions examples/08_account_abstraction.zig

Large diffs are not rendered by default.

141 changes: 141 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This directory contains comprehensive examples demonstrating the most common Eth
| **5** | `05_transaction_receipts.zig` | Transaction receipts and status | ⭐⭐ Intermediate |
| **6** | `06_event_monitoring.zig` | Event monitoring and subscriptions | ⭐⭐⭐ Advanced |
| **7** | `07_complete_workflow.zig` | Complete end-to-end workflow | ⭐⭐⭐ Advanced |
| **8** | `08_account_abstraction.zig` | ERC-4337 Account Abstraction (AA) | ⭐⭐⭐ Advanced |

## 🚀 Running Examples

Expand Down Expand Up @@ -194,6 +195,48 @@ Learn how to:

**Use cases**: Complete applications, learning the full API

### 8. Account Abstraction (`08_account_abstraction.zig`)

Learn how to:
- Work with ERC-4337 Account Abstraction
- Use all three EntryPoint versions (v0.6, v0.7, v0.8)
- Create and manage smart contract accounts
- Integrate with bundlers and paymasters
- Estimate gas for UserOperations
- Encode single and batch transactions
- Use paymaster sponsorship
- Build complete AA workflows

**Topics covered**:
- EntryPoint versions and multi-version support
- UserOperation creation (v0.6, v0.7, v0.8)
- Smart Account creation with CREATE2
- Factory-based account deployment
- Gas estimation (local and RPC)
- Paymaster integration (SPONSOR and ERC20 modes)
- Bundler client usage
- Transaction encoding (execute and executeBatch)
- Complete sponsored transaction workflow

**Use cases**:
- Smart contract wallets
- Sponsored dApps (gasless transactions)
- ERC-20 fee payment wallets
- Multi-signature wallets
- Social recovery wallets
- DeFi applications with Account Abstraction
- Gaming platforms with free transactions

**Key Features Demonstrated**:
- ✅ Compile-time polymorphism (anytype)
- ✅ Multi-version UserOperations
- ✅ Zero runtime overhead
- ✅ Type-safe bundler/paymaster clients
- ✅ CREATE2 deterministic addresses
- ✅ Batch atomic transactions
- ✅ Paymaster data packing/unpacking
- ✅ Version conversion (v0.7 → v0.6)

## 🎯 Common Patterns

### Pattern 1: Simple Address Creation
Expand Down Expand Up @@ -265,6 +308,85 @@ const call_data = try zigeth.abi.encodeFunctionCall(allocator, balance_of, &para
// Use provider.eth.call() to execute
```

### Pattern 5: Account Abstraction - Sponsored Transaction

```zig
const aa = zigeth.account_abstraction;

// 1. Setup
const entry_point = try aa.EntryPoint.v07(allocator, &rpc_client);
var smart_account = aa.SmartAccount.init(
allocator,
account_address,
entry_point.address,
.v0_7,
owner_address,
&rpc_client,
&factory,
0, // salt
);

// 2. Create transaction
const call_data = try smart_account.encodeExecute(
recipient_address,
value, // Amount in wei
&[_]u8{}, // Additional data if needed
);
defer allocator.free(call_data);

// 3. Estimate gas
var gas_estimator = aa.GasEstimator.init(allocator, null, &rpc_client);
const test_op = aa.UserOpUtils.zero(aa.types.UserOperationV07);
const gas_estimates = try gas_estimator.estimateGas(test_op);

// 4. Create UserOperation
const user_op_any = try smart_account.createUserOperation(call_data, gas_estimates);
var user_op = user_op_any.v07;

// 5. Get paymaster sponsorship (FREE for user!)
var paymaster = aa.PaymasterClient.init(allocator, paymaster_url, api_key);
defer paymaster.deinit();
try paymaster.sponsorUserOperation(&user_op, entry_point.address, .sponsor);

// 6. Sign
const signature = try smart_account.signUserOperation(user_op, private_key);
defer allocator.free(signature);
user_op.signature = signature;

// 7. Send to bundler
var bundler = aa.BundlerClient.init(allocator, bundler_url, entry_point.address);
defer bundler.deinit();
const user_op_hash = try bundler.sendUserOperation(user_op);

// 8. Wait for execution
const receipt = try bundler.getUserOperationReceipt(user_op_hash);
std.debug.print("Success: {}\n", .{receipt.?.success});
```

### Pattern 6: Account Abstraction - Batch Transactions

```zig
// Execute multiple calls atomically
const batch_calls = [_]aa.Call{
.{
.to = usdc_address,
.value = 0,
.data = try encodeApprove(spender, amount), // Approve USDC
},
.{
.to = dex_address,
.value = 0,
.data = try encodeSwap(usdc_address, eth_address, amount), // Swap on DEX
},
};

const call_data = try smart_account.encodeExecuteBatch(&batch_calls);
defer allocator.free(call_data);

// Create UserOperation and send (same as Pattern 5)
// If one call fails, entire batch reverts (atomic)
```

## ⚠️ Important Notes

### Testnet Usage
Expand Down Expand Up @@ -339,6 +461,15 @@ zigeth.signer.Wallet
5. Study `05_transaction_receipts.zig` - Understand receipts
6. Experiment with `06_event_monitoring.zig` - Real-time events
7. Master `07_complete_workflow.zig` - Put it all together
8. **Advanced**: `08_account_abstraction.zig` - ERC-4337 and smart accounts

**Alternative path for Account Abstraction developers:**

1. `01_wallet_creation.zig` - Understand EOA (Externally Owned Accounts)
2. `02_query_blockchain.zig` - Learn blockchain queries
3. `08_account_abstraction.zig` - Jump into smart contract accounts
4. `04_smart_contracts.zig` - Understand contract interactions (AA uses these!)
5. `07_complete_workflow.zig` - Traditional workflow comparison

## 🌐 Multi-Chain Support

Expand Down Expand Up @@ -395,12 +526,22 @@ Have a useful example? Contributions are welcome!

## 🔗 Additional Resources

### General Ethereum Development
- [Zigeth Documentation](../README.md)
- [Zig Language](https://ziglang.org/learn/)
- [Ethereum Documentation](https://ethereum.org/en/developers/)
- [Etherspot RPC](https://etherspot.io/)
- [EIP Specifications](https://eips.ethereum.org/)

### Account Abstraction (ERC-4337)
- [EIP-4337 Specification](https://eips.ethereum.org/EIPS/eip-4337) - Official ERC-4337 standard
- [Account Abstraction README](../src/account_abstraction/README.md) - Zigeth AA package documentation
- [eth-infinitism/account-abstraction](https://github.com/eth-infinitism/account-abstraction) - Reference Solidity contracts
- [Viem Account Abstraction](https://viem.sh/account-abstraction) - TypeScript reference
- [Etherspot Skandha](https://github.com/etherspot/skandha) - Open-source bundler
- [Etherspot Arka](https://github.com/etherspot/arka) - Open-source paymaster
- [ERC-4337 Resources](https://www.erc4337.io/) - Community resources

## 📞 Support

- **Issues**: https://github.com/ch4r10t33r/zigeth/issues
Expand Down
50 changes: 30 additions & 20 deletions examples/account_abstraction_example.zig
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
const std = @import("std");
const zigeth = @import("zigeth");

/// Comprehensive Account Abstraction (ERC-4337) Example
/// Demonstrates all major features of the AA package
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();

std.debug.print("\n", .{});
std.debug.print("=" ** 60 ++ "\n", .{});
std.debug.print("Zigeth Account Abstraction (ERC-4337) Example\n", .{});
std.debug.print("=" ** 60 ++ "\n\n", .{});

// 1. Show all EntryPoint versions
std.debug.print("1. EntryPoint Versions:\n", .{});
std.debug.print("=" ** 80 ++ "\n", .{});
std.debug.print(" Zigeth Account Abstraction (ERC-4337) - Comprehensive Example\n", .{});
std.debug.print("=" ** 80 ++ "\n\n", .{});

// ============================================================================
// SECTION 1: EntryPoint Versions
// ============================================================================
std.debug.print("┌─────────────────────────────────────────────────────────────────────────┐\n", .{});
std.debug.print("│ SECTION 1: EntryPoint Versions │\n", .{});
std.debug.print("└─────────────────────────────────────────────────────────────────────────┘\n\n", .{});

std.debug.print(" v0.6 (Legacy):\n", .{});
std.debug.print(" Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V06_ADDRESS});
var entry_point_v06 = try zigeth.account_abstraction.EntryPoint.v06(allocator);
std.debug.print(" Version: {:?}\n", .{entry_point_v06.version});
std.debug.print(" EntryPoint v0.6 (Legacy - Original ERC-4337):\n", .{});
std.debug.print(" • Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V06_ADDRESS});
var entry_point_v06 = try zigeth.account_abstraction.EntryPoint.v06(allocator, null);
std.debug.print(" • Version: {}\n", .{entry_point_v06.version});
std.debug.print(" • Gas fields: u256 (larger, less efficient)\n\n", .{});

std.debug.print(" v0.7 (Current - Gas-optimized):\n", .{});
std.debug.print(" Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V07_ADDRESS});
var entry_point_v07 = try zigeth.account_abstraction.EntryPoint.v07(allocator);
std.debug.print(" Version: {:?}\n", .{entry_point_v07.version});
std.debug.print(" EntryPoint v0.7 (Current - Gas-optimized):\n", .{});
std.debug.print(" • Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V07_ADDRESS});
var entry_point_v07 = try zigeth.account_abstraction.EntryPoint.v07(allocator, null);
std.debug.print(" • Version: {}\n", .{entry_point_v07.version});
std.debug.print(" • Gas fields: u128 (smaller, more efficient)\n", .{});
std.debug.print(" • Separate factory and paymaster fields\n\n", .{});

std.debug.print(" v0.8 (Future):\n", .{});
std.debug.print(" Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V08_ADDRESS});
var entry_point_v08 = try zigeth.account_abstraction.EntryPoint.v08(allocator);
std.debug.print(" Version: {:?}\n\n", .{entry_point_v08.version});
std.debug.print(" EntryPoint v0.8 (Latest):\n", .{});
std.debug.print(" • Address: {s}\n", .{zigeth.account_abstraction.EntryPoint.ENTRYPOINT_V08_ADDRESS});
var entry_point_v08 = try zigeth.account_abstraction.EntryPoint.v08(allocator, null);
std.debug.print(" • Version: {}\n", .{entry_point_v08.version});
std.debug.print(" • Additional optimizations\n\n", .{});

// Use v0.7 for rest of example
var entry_point = entry_point_v07;
// Use v0.7 for rest of example (gas-optimized)
const entry_point = entry_point_v07;

// 2. Create Smart Account
std.debug.print("2. Creating Smart Account...\n", .{});
Expand Down
29 changes: 19 additions & 10 deletions src/account_abstraction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,30 @@ const result = try entry_point.simulateValidation(user_op);

## Implementation Status

| Component | Status | Description |
|-----------|--------|-------------|
| UserOperation Types | ✅ Complete | All data structures defined |
| Bundler Client | 🟡 Stub | Interface ready, RPC calls TODO |
| Paymaster Client | 🟡 Stub | Interface ready, RPC calls TODO |
| Smart Account | 🟡 Stub | Interface ready, ABI encoding TODO |
| EntryPoint | 🟡 Stub | Interface ready, contract calls TODO |
| Gas Estimation | 🟡 Partial | Basic estimation, needs refinement |
| Utilities | 🟡 Partial | Structures ready, hashing TODO |
| Component | Status | Functions | Description |
|-----------|--------|-----------|-------------|
| UserOperation Types | ✅ Complete | 7/7 | All data structures, conversions, and serialization |
| Bundler Client | ✅ Complete | 6/6 | Full RPC integration, multi-version support |
| Paymaster Client | ✅ Complete | 9/9 | Sponsorship, ERC-20 quotes, data parsing |
| Smart Account | ✅ Complete | 10/10 | Creation, signing, deployment, batch execution |
| EntryPoint | ✅ Core | 4/6 | Nonce, balance, deposits (simulateValidation & handleOps are stubs) |
| Gas Estimation | ✅ Complete | 10/10 | RPC + local fallback, EIP-1559, all versions |
| Utilities | ✅ Complete | 7/7 | Hashing, packing, validation, all versions |

**Overall: 46/48 functions (95.8%) - Production Ready! 🚀**

**Legend:**
- ✅ Complete - Fully implemented and tested
- ✅ Complete - Fully implemented, tested, and production-ready
- ✅ Core - Core functions complete, optional functions are stubs
- 🟡 Stub/Partial - Interface defined, implementation in progress
- ❌ Planned - Not yet started

**Notes:**
- All modules support EntryPoint v0.6, v0.7, and v0.8
- Multi-version support via compile-time polymorphism (anytype)
- Full JSON-RPC integration for bundler and paymaster
- The 2 stub functions (simulateValidation, handleOps) require complex ABI encoding and are not needed for most AA workflows

## Testing

```bash
Expand Down
2 changes: 2 additions & 0 deletions src/account_abstraction/account_abstraction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub const BundlerClient = bundler.BundlerClient;
pub const PaymasterClient = paymaster.PaymasterClient;
pub const PaymasterMode = paymaster.PaymasterMode;
pub const TokenQuote = paymaster.TokenQuote;
pub const PaymasterStub = paymaster.PaymasterStub;

// Re-export smart account
pub const SmartAccount = smart_account.SmartAccount;
Expand All @@ -53,6 +54,7 @@ pub const GasOverhead = gas.GasOverhead;

// Re-export utilities
pub const UserOpHash = utils.UserOpHash;
pub const UserOpUtils = utils.UserOpUtils;
pub const PackedUserOperation = utils.PackedUserOperation;

test {
Expand Down
Loading
Loading