# OUTDATED: BLSWallet 4337 Interop ## Summary - Create a 4337 `EntryPoint` contract which converts the 4337 `UserOperation` to a `Bundle` and calls `processBundle` on the `VerificationGateway` - Include `simulateValidation` by doing the same thing, include `require(msg.sender == address(0))`, and just return `(0,0)` for `(preOpGas,prefund)` - This way, when a wallet makes an `eth_sendUserOperation` call, the node can accept it into the 4337 `UserOperation` mempool - Once in the `UserOperation` mempool, participants that are aware of our 4337 `EntryPoint` can convert these `UserOperation`s into bundles, aggregate them (taking advantage of BLS signature aggregation), and submit the `processBundle` call if it is profitable for them to do so ## How Wallets Can Integrate BLSWallet This Way Wallets still need to know how to convert an `eth_sendTransaction` call into a BLSWallet appropriate `eth_sendUserOperation` call. We can provide a module to help with this. It's expected that a wallet will write something like this: ```js= async function handle_eth_sendTransaction(tx) { const blsPrivateKey = lookupBlsPrivateKey(tx.from); if (blsPrivateKey === undefined) { // Error / handle non-BLSWallet account } const userOperation = blsWallet4337.txToUserOperation(tx, blsPrivateKey); return await request({ method: 'eth_sendUserOperation', params: [userOperation, blsWallet4337.entryPointAddress], }); } ``` There's also a setup requirement. Transactions and `UserOperation`s use an address to identify the contract wallet and `processBundle` requires the BLS public key instead. The Wallet will need to explicitly initialize the contract wallet so that the `VerificationGateway` will store the mapping: ```js= async function initWallet(privateKey) { const wallet = await BlsWalletWrapper.connect( privateKey, verificationGateway.address, provider, ); const bundle = wallet.sign({ nonce: 0, actions: [], }); await verificationGateway.processBundle(bundle); } ``` ## Draft of BLSWallet's 4337 `EntryPoint` ```solidity= contract EntryPoint { function handleOps( UserOperation[] calldata ops, address payable beneficiary ) public { for (uint i = 0; i < ops.length; i++) { _handleOp(ops[i]); } } function simulateValidation( UserOperation calldata op ) external returns (uint preOpGas, uint prefund) { require(msg.sender == address(0), "must be called off-chain with from=zero-addr"); _handleOp(op); preOpGas = 0; prefund = 0; } function _handleOp( UserOperation calldata op ) private { uint[BLS_KEY_LEN][] memory senderPublicKeys = new uint[BLS_KEY_LEN][](1); senderPublicKeys[0] = verificationGateway.walletFromHash[ verificationGateway.hashFromWallet[op.sender] ]; IWallet.Operation[] memory operations = new IWallet.Operation[](1); operations[0].nonce = op.nonce; operations[0].actions = op.callData; // TODO: bytes->actions conversion Bundle memory bundle = Bundle({ signature: op.signature, // TODO: bytes->uint[2] conversion senderPublicKeys: senderPublicKeys, }); verificationGateway.processBundle(toBundle(ops[i])); } } ``` ## Work to Be Done 1. `EntryPoint` contract 2. `blsWallet4337` npm module to assist wallet integration (or extend `bls-wallet-clients`) 3. Add to aggregator or create aggregator-like node that participates in the `UserOperation` mempool to submit bundles ## Potential Issues - 4337 is prescriptive about how the `EntryPoint` and associated wallets work (in ways that don't fit BLS Wallet). These don't seem to be necessary, but could cause adoption concerns. ## Links - [EIP-4337](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4337.md) - [Reference implementation of 4337 `EntryPoint`](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/core/EntryPoint.sol)