EIP idea: eth_signUserOperation RPC

Sorry, do you mean just not allowing sequence to be passed alone? I think that could make sense. Probably key can still be passed alone though.

Sorry, was not thinking here. We probably just stick to eth_signerUserOperation. eth_sendUserOperation is already specified in the original EIP. The original schema I proposed was closer to that definition. Perhaps we could still keep convention of empty bytes being 0x rather than fields being absent?

From the EIP:

Parameters:
1. **UserOperation** a full user-operation struct. All fields MUST be set as hex values. empty `bytes` block (e.g. empty `initCode`) MUST be set to `"0x"`
2. **EntryPoint** the entrypoint address the request should be sent through. this MUST be one of the entry points returned by the `supportedEntryPoints` rpc call.

UNLESS we want to extend the original EIP to define a version of eth_sendUserOperation that does not require a signature, so that it is closer to eth_sendTransaction.

But yeah, as it is, I’m not sure we need eth_sendRawUserOperation? The expectation of eth_sendUserOperation already is that it is a signed payload.

Thanks for this! Definitely agree this is an under-specified part of the EIP.

I think this may just be an oversight, but should the hashedUserOperation in your example be hashed with keccak256, e.g.:

Oops yes thanks it should.

Why would you need to sign a UserOperation (or a transaction, for that matter)
It requires the user to pre-fill all fields (instead of letting the wallet to do it), and also prevents the wallet from adjusting the gas in “real-time”.
With UserOperation, it also takes the wallet’s ability to inject a paymaster.

Looks to me like it tries to mimic an obsolete feature of node (e.g. eth_sign of geth) - as production nodes never support such a method, and the sending (and signing) a transaction is purely a wallet API.

Hi!

It requires the user to pre-fill all fields (instead of letting the wallet to do it), and also prevents the wallet from adjusting the gas in “real-time”.
With UserOperation, it also takes the wallet’s ability to inject a paymaster.

This is just giving dapps and wallets the ability to communicate more robustly about userOperations. As I said in the OP

Suppose the dapp has its own paymaster, which my wallet knows nothing about, and wants to include the paymaster and signature in the request sent to the wallet. Perhaps the dapp wants to set some of the user operation gas values, and help the wallet with things it may not be aware of. Currently there is no way to do these things.

The wallet is still free to adjust the fields the dapp has set in the userOp, just as a wallet can adjust the field set in eth_sendTransaction.

Looks to me like it tries to mimic an obsolete feature of node (e.g. eth_sign of geth) - as production nodes never support such a method, and the sending (and signing) a transaction is purely a wallet API.

Would you prefer that dapps make eth_sendUserOperation calls to the wallet? How can we get to a place where wallets can show rich/useful info to the user about the userOp they are being asked to sign, and allow users to edit various fields just like they can edit any other transaction?

I am not opposed to leveraging eth_sendUserOperation to be more like eth_sendTransaction which signs and submits the transaction. This just seems contrary to my understanding of the current spec.

No sorry, I was just playing around with more concise ways to represent nonce/key+sequence as mutually exclusive. Totally forgot about sequence and key being passed on their own.

First, Metamask or any other EOA wallet should not be used in production with UserOperations: there is no way to show the user the operation he signs on.
The only use of Metamask and such with personal_sign was for demonstrative purposes, because there was no alternative wallet.
We should update the sample “SimpleAccount” contract, and clearly explain that this is a sample only, and should not use this signature scheme for any production wallet.

Existing EOA wallets are not expected to be used with AA exactly for this reason. You need AA-specific wallet, which might be able to import your EOA settings to be used as a signer key.

The userOpHash is defined in the EntryPoint implementation (getUserOpHash())
We should add this definition into the ERC itself.

Regarding filling in fields:
A paymaster is something that can either be set by the dApp, or by the wallet.
If the application fills it in, the wallet is expected to use it.
If the dApp didn’t fill in the paymaster (which means, the application doesn’t care about actual payment model), the wallet may use its own configuration and fill in a paymaster.
In any case, when displaying the UserOp to the user, the user may select to change the paymaster - but this is up to the wallet UX to decide.

1 Like

Thanks for the feedback!

Exactly! That’s a motivation behind this post: there should be an RPC that any wallet could implement to show a user useful signing info for user ops and allow that user to engage in 4337 transactions. Some users may like their existing wallet for whatever reason and not want to migrate key materials. We’ve already heard from ThirdWeb and others that their SDKs would probably support the big consumer wallets as signers if such an RPC existed. I see no downside in specifying this.

Regarding filling in fields:
A paymaster is something that can either be set by the dApp, or by the wallet.
If the application fills it in, the wallet is expected to use it.
If the dApp didn’t fill in the paymaster (which means, the application doesn’t care about actual payment model), the wallet may use its own configuration and fill in a paymaster.
In any case, when displaying the UserOp to the user, the user may select to change the paymaster - but this is up to the wallet UX to decide.

OK, so to be clear, you’re saying here that the AA wallet is receiving an eth_sendUserOperation call, right? If so I think the 4337 EIP could better specify that the eth_sendUserOperation does not have to have a valid signature.

1 Like

I see two paths, I think.

  1. Make a minimal update to EIP-4337 to express that eth_sendUserOperation can not include a signature and should be used for communicating with Wallets.

  2. Make a new EIP defining more comprehensive RPCs for signing and submitting user operations

  • eth_sendUserOperation, mirrors eth_sendTransaction. Receives a user op with no signature, signs and submits.
  • eth_sendRawUserOperation, mirrors eth_sendRawTransaction. Bytes of a user operation that includes a signature.
  • eth_signUserOperation, mirrors eth_signTransaction. Maybe not necessary, as eth_signTransaction is not highly used, but allows apps to ask wallets for a signature and still controls the bundler that gets used.

Path 2. might require removing eth_sendUserOperation spec from the original EIP? Would love thoughts!

Or perhaps also,

  1. Keep with the original intent of this post. Define only eth_signUserOperation and leave everything else alone.

I am not totally satisfied with this, though. Long term I think it makes sense for Wallets to pick bundlers and submit the user operation, just as they pick which node to send an eth transaction to. I’d expect wallets to prefer eth_sendUserOperation, just as they prefer eth_sendTransaction over eth_signTransaction.

To follow up here, after a long path we ended up updating EIP-5792 to meet these needs. Discussed here https://x.com/WilsonCusack/status/1774517632743428317?s=20

1 Like