Claude-skill-registry erc4337-privacy-wallet
Privacy-preserving ERC-4337 wallet development for vehicle identity and sensitive data protection. Use when implementing ERC-4337 account abstraction wallets that handle sensitive information (vehicle license plates, biometric data, personal IDs) requiring on-chain privacy. Triggers on requests like "implement ERC-4337 wallet for vehicle", "create privacy-protected account abstraction", "build wallet with vehicle number privacy", "develop ERC-4337 with ZK proof integration", or any smart contract wallet development requiring commitment schemes, deterministic address generation, and sensitive data protection.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/erc4337-privacy-wallet-dev" ~/.claude/skills/majiayu000-claude-skill-registry-erc4337-privacy-wallet && rm -rf "$T"
skills/data/erc4337-privacy-wallet-dev/SKILL.mdERC-4337 Privacy-Protected Wallet
Overview
This skill provides comprehensive support for developing ERC-4337 compliant Account Abstraction wallets with privacy-preserving features, specifically designed for vehicle identity and other sensitive data use cases. It combines smart contract templates, testing frameworks, privacy validation tools, and security best practices to enable the secure implementation of wallets that protect user privacy while maintaining on-chain functionality.
Key Capabilities:
- Privacy-protected smart contract templates (PrivacyProtectedAccount, AccountFactory, VehicleRegistry)
- Commitment scheme implementation for sensitive data (vehicle plates, personal info)
- Deterministic address generation using CREATE2
- Comprehensive test suites with privacy verification
- Automated privacy validation tooling
- Security and compliance checklists
When to Use This Skill
Invoke this skill when you encounter requests involving:
- Vehicle Identity Wallets: "Create a wallet from vehicle license plate information"
- ERC-4337 Implementation: "Implement account abstraction for privacy-protected accounts"
- Sensitive Data Protection: "Build wallet that hides user's personal identification"
- Deterministic Address Generation: "Generate predictable wallet addresses from private data"
- ZK Proof Integration: "Add zero-knowledge proof verification to ERC-4337 wallet"
- Privacy Auditing: "Validate that my smart contract doesn't leak sensitive information"
Quick Start Guide
1. Understand the Requirements
Ask the user these key questions:
- What sensitive data needs protection? (vehicle plate, biometric, etc.)
- Is deterministic address generation required?
- Are ZK proofs needed, or is commitment hashing sufficient?
- What is the target blockchain/testnet?
2. Set Up the Project
# Copy contract templates cp -r assets/contracts/* ./contracts/ # Install dependencies cd contracts npm install # Compile contracts npm run compile
3. Customize for Your Use Case
For vehicle-based wallets:
// Off-chain: Compute vehicle commitment const plateNumber = "ABC-1234"; const userSalt = ethers.id("user-secret-entropy"); const commitment = ethers.keccak256( ethers.solidityPacked(["string", "bytes32"], [plateNumber, userSalt]) ); // Deploy account with commitment const account = await factory.createAccount( ownerAddress, commitment, 12345 // deployment salt );
For biometric/other sensitive data:
// Replace plateNumber with your sensitive data const biometricHash = computeHash(biometricData); const commitment = ethers.keccak256( ethers.solidityPacked(["bytes32", "bytes32"], [biometricHash, userSalt]) );
4. Run Privacy Validation
# Validate that contracts don't leak sensitive data python scripts/validate_privacy.py contracts/PrivacyProtectedAccount.sol
5. Run Tests
# Run comprehensive test suite npm test # Run specific test file npx hardhat test tests/PrivacyProtectedAccount.test.ts
Core Components
1. PrivacyProtectedAccount
The main account contract that implements ERC-4337's
IAccount interface with privacy features.
Key Features:
- Stores only commitment (hash) of sensitive data, never raw values
- Deterministic address generation via CREATE2
- ERC-4337 compliant UserOperation validation
- Owner-based access control
- Batch transaction execution
Usage:
// Deploy via factory const account = await factory.createAccount(owner, vehicleCommitment, salt); // Verify ownership without revealing data const isValid = await account.verifyVehicleOwnership(plateNumber, userSalt); // Execute transaction await account.execute(targetAddress, value, calldata);
Privacy Guarantee:
- Vehicle commitment is stored as
hashbytes32 - Raw plate number never touches blockchain
- Verification is view-only (off-chain safe)
2. AccountFactory
Factory contract for deploying PrivacyProtectedAccount instances with deterministic addresses.
Key Features:
- CREATE2-based deterministic deployment
- Counterfactual address computation
- Batch account creation
- Cross-chain address consistency
Usage:
// Compute address before deployment const predictedAddress = await factory.getAddress(owner, commitment, salt); // Deploy account const account = await factory.createAccount(owner, commitment, salt); // Address matches prediction assert(accountAddress === predictedAddress);
Use Cases:
- Receive funds before account creation
- Consistent addresses across multiple chains
- Privacy-preserving wallet generation
3. VehicleRegistry
Optional registry contract for managing vehicle-to-wallet mappings with privacy.
Key Features:
- Maps commitments to wallet addresses
- Authorized verifier system
- Selective disclosure support
- Batch registration
Usage:
// Register vehicle with commitment only await registry.registerVehicle(commitment, walletAddress, metadataHash); // Verify registration (authorized only) const isRegistered = await registry.verifyVehicleRegistration(commitment); // Update commitment (ownership transfer) await registry.updateVehicleCommitment(oldCommitment, newCommitment);
Implementation Workflow
Step 1: Define Privacy Model
Determine what needs privacy protection:
Example - Vehicle Wallet:
Sensitive: License plate number Public: Wallet address, transaction history Commitment: keccak256(plateNumber + salt)
Example - Biometric Wallet:
Sensitive: Fingerprint hash Public: Wallet address Commitment: keccak256(fingerprintHash + salt)
Step 2: Generate Commitment Off-Chain
CRITICAL: Never pass raw sensitive data to blockchain functions.
// Frontend/Backend - OFF-CHAIN computation import { ethers } from 'ethers'; function generateCommitment(sensitiveData, userSecret) { // Generate cryptographically secure salt const salt = ethers.keccak256( ethers.solidityPacked( ['string', 'uint256', 'address'], [userSecret, Date.now(), userAddress] ) ); // Compute commitment const commitment = ethers.keccak256( ethers.solidityPacked(['string', 'bytes32'], [sensitiveData, salt]) ); return { commitment, salt }; } // Usage const { commitment, salt } = generateCommitment(licensePlate, userSecret); // Store salt securely off-chain! // Send only commitment to blockchain
Step 3: Deploy Account
// Connect to factory const factory = await ethers.getContractAt('AccountFactory', factoryAddress); // Optional: Predict address first const predictedAddress = await factory.getAddress( ownerAddress, commitment, deploymentSalt ); console.log('Account will be deployed at:', predictedAddress); // Deploy account const tx = await factory.createAccount(ownerAddress, commitment, deploymentSalt); await tx.wait(); console.log('Account deployed at:', predictedAddress);
Step 4: Create and Submit UserOperation
import { ethers } from 'ethers'; // Build UserOperation const userOp = { sender: accountAddress, nonce: await account.getNonce(), initCode: '0x', // Empty if account exists callData: account.interface.encodeFunctionData('execute', [ targetAddress, value, data ]), accountGasLimits: ethers.solidityPacked( ['uint128', 'uint128'], [verificationGasLimit, callGasLimit] ), preVerificationGas, gasFees: ethers.solidityPacked( ['uint128', 'uint128'], [maxPriorityFeePerGas, maxFeePerGas] ), paymasterAndData: '0x', // Or paymaster address + data signature: '0x' // Will be filled after signing }; // Sign UserOperation const userOpHash = await account.getUserOpHash(userOp); const signature = await owner.signMessage(ethers.getBytes(userOpHash)); userOp.signature = signature; // Submit to bundler await bundler.sendUserOperation(userOp);
Step 5: Verify Privacy Protection
# Run automated privacy validation python scripts/validate_privacy.py contracts/YourContract.sol # Expected output: # ✅ PRIVACY VALIDATION PASSED # No privacy violations detected.
Privacy Patterns
Pattern 1: Basic Commitment
// Off-chain const commitment = keccak256(abi.encodePacked(sensitiveData, salt)); // On-chain bytes32 public dataCommitment; function initialize(bytes32 _commitment) external { dataCommitment = _commitment; } function verify(string memory data, bytes32 salt) external view returns (bool) { return keccak256(abi.encodePacked(data, salt)) == dataCommitment; }
Pattern 2: Multi-Attribute Commitment
// For vehicles with multiple attributes struct VehicleData { string plateNumber; string model; uint256 year; } // Off-chain const commitment = keccak256(abi.encode( vehicleData.plateNumber, vehicleData.model, vehicleData.year, salt ));
Pattern 3: ZK Proof Integration
For advanced privacy (see
references/privacy-patterns.md for full examples):
// Verify ZK proof instead of revealing data function _validateSignature( PackedUserOperation calldata userOp, bytes32 userOpHash ) internal override returns (uint256) { (bytes memory proof, bytes memory publicInputs) = abi.decode(userOp.signature, (bytes, bytes)); require(zkVerifier.verify(proof, publicInputs), "Invalid proof"); return SIG_VALIDATION_SUCCESS; }
Testing Strategy
Privacy Tests
describe("Privacy Protection", () => { it("should not store raw sensitive data", async () => { // Verify storage doesn't contain plate number for (let i = 0; i < 20; i++) { const storage = await ethers.provider.getStorage(account.address, i); expect(storage).to.not.include(ethers.hexlify(ethers.toUtf8Bytes(plateNumber))); } }); it("should verify with correct preimage", async () => { const isValid = await account.verifyVehicleOwnership(plateNumber, salt); expect(isValid).to.be.true; }); it("should reject wrong preimage", async () => { const isValid = await account.verifyVehicleOwnership("WRONG-PLATE", salt); expect(isValid).to.be.false; }); });
ERC-4337 Tests
describe("UserOperation Validation", () => { it("should validate correct signature", async () => { const userOp = buildUserOp({ sender: account.address }); const userOpHash = await entryPoint.getUserOpHash(userOp); userOp.signature = await owner.signMessage(ethers.getBytes(userOpHash)); await expect(entryPoint.handleOps([userOp], bundler.address)) .to.not.be.reverted; }); });
Security Checklist
Before deploying to mainnet, verify:
- Run privacy validation:
python scripts/validate_privacy.py - All tests passing:
npm test - No raw sensitive data in storage or events
- Commitment generation uses strong salt (≥256 bits entropy)
- Verification functions are
orviewpure - Access control properly implemented
- EntryPoint address is correct
- Contracts verified on Etherscan
- Professional security audit completed
See
references/security-checklist.md for complete checklist.
Common Pitfalls
❌ Storing Raw Sensitive Data
// NEVER DO THIS contract BadExample { string public licensePlate; // Publicly visible! }
✅ Correct Approach
// DO THIS contract GoodExample { bytes32 public vehicleCommitment; // Only hash stored }
❌ Weak Salt Generation
// WEAK - predictable bytes32 salt = bytes32(block.timestamp);
✅ Strong Salt
// STRONG - unique per user with high entropy bytes32 salt = keccak256(abi.encodePacked( userSecret, block.timestamp, block.prevrandao, msg.sender ));
❌ Exposing Data in Events
// NEVER DO THIS event VehicleRegistered(string plateNumber);
✅ Events with Commitments
// DO THIS event VehicleRegistered(bytes32 indexed commitment);
Advanced Topics
ZK-SNARK Integration
For zero-knowledge proof integration, see
references/privacy-patterns.md section on ZK proofs.
High-level flow:
- Generate ZK circuit for vehicle ownership
- Prove knowledge of plate number without revealing it
- Verify proof on-chain in
_validateSignature()
Cross-Chain Deployment
# Deploy to multiple networks with same addresses npx hardhat run scripts/deploy.ts --network sepolia npx hardhat run scripts/deploy.ts --network polygonAmoy # Addresses match due to CREATE2 determinism
Gasless Transactions with Paymaster
// Add paymaster to UserOperation userOp.paymasterAndData = ethers.solidityPacked( ['address', 'bytes'], [paymasterAddress, paymasterData] ); // User doesn't pay gas - paymaster sponsors it
Resources
Bundled Resources
-
: Production-ready contract templatesassets/contracts/
- Main account contractPrivacyProtectedAccount.sol
- Deterministic factoryAccountFactory.sol
- Optional registryVehicleRegistry.sol
,package.json
- Project setuphardhat.config.ts
-
: Comprehensive test suitesassets/tests/- Privacy protection tests
- ERC-4337 compliance tests
- Gas optimization tests
-
: Automated privacy validation toolscripts/validate_privacy.py- Scans for sensitive data leaks
- Validates commitment patterns
- Checks event safety
-
: In-depth documentationreferences/
- ERC-4337 deep diveerc4337-architecture.md
- Privacy implementation patternsprivacy-patterns.md
- Comprehensive security guidesecurity-checklist.md
External Resources
- ERC-4337 Specification
- Account Abstraction Docs
- MynaWallet Reference
- Toyota MON
- OpenZeppelin Contracts
Support and Troubleshooting
Common Issues
Issue: Gas estimation fails
Solution: Ensure account has sufficient deposit in EntryPoint await account.addDeposit({ value: ethers.parseEther("0.1") });
Issue: Signature validation fails
Solution: Check that userOpHash is computed correctly const userOpHash = await entryPoint.getUserOpHash(userOp);
Issue: Privacy validation fails
Solution: Review reported violations and fix - Remove string storage for sensitive data - Make verification functions view/pure - Use commitments instead of raw data
Getting Help
- Check
for detailed documentationreferences/ - Review test files for usage examples
- Run privacy validation for security issues
- Consult ERC-4337 documentation for protocol questions