Skip to content

Add EIP: Flow Control Wallet Call Capability#9259

Merged
eth-bot merged 9 commits intoethereum:masterfrom
SamWilsn:eip-call-flow-control
Mar 12, 2025
Merged

Add EIP: Flow Control Wallet Call Capability#9259
eth-bot merged 9 commits intoethereum:masterfrom
SamWilsn:eip-call-flow-control

Conversation

@SamWilsn
Copy link
Copy Markdown
Contributor

No description provided.

@SamWilsn SamWilsn requested a review from eth-bot as a code owner January 22, 2025 19:10
@github-actions github-actions Bot added c-new Creates a brand new proposal s-draft This EIP is a Draft t-interface labels Jan 22, 2025
@eth-bot
Copy link
Copy Markdown
Collaborator

eth-bot commented Jan 22, 2025

✅ All reviewers have approved.

@eth-bot eth-bot added e-consensus Waiting on editor consensus e-review Waiting on editor to review labels Jan 22, 2025
@eth-bot eth-bot changed the title Add EIP: EIP-5792 flow control Add EIP: Flow Control Wallet Call Capability Jan 22, 2025
@github-actions github-actions Bot added the w-ci Waiting on CI to pass label Jan 22, 2025
@SamWilsn SamWilsn force-pushed the eip-call-flow-control branch from 64b1893 to 114bb1c Compare January 22, 2025 19:15
Copy link
Copy Markdown
Contributor

@Marchhill Marchhill left a comment

Choose a reason for hiding this comment

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

A few nitpicks

Comment thread EIPS/eip-draft_wallet-call-flow-control.md Outdated
Comment thread EIPS/eip-draft_wallet-call-flow-control.md Outdated

#### Rollback

A rollback is informally defined as "causing no meaningful changes on chain." A
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there any reason to break up lines like this? A paragraph could be on one line and use line wrapping, not sure what the standard is here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I like a narrow line width, but we accept both wrapped and unwrapped lines.

Comment thread EIPS/eip-draft_wallet-call-flow-control.md Outdated
Comment thread EIPS/eip-draft_wallet-call-flow-control.md Outdated
| `207` | Partial Success |

An "included" call, in this section, is defined as having either been
successfully or unsuccessfully executed. A call that has been recorded on chain,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
successfully or unsuccessfully executed. A call that has been recorded on chain,
executed, even if execution was unsuccessful. A call that has been recorded on chain,


Status `102` SHALL be returned only when all of the following are true:

* At least one call in the batch has been included on chain; and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* At least one call in the batch has been included on chain; and
* At least one call in the batch has been included on chain.

Comment thread EIPS/eip-draft_wallet-call-flow-control.md Outdated

Status `207` SHALL be returned only when all of the following are true:

* At least one call in the batch has been included and succeeded;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
* At least one call in the batch has been included and succeeded;
* At least one call in the batch has been included and succeeded.

Same for rest of list, for consistency with other lists


## Backwards Compatibility

<!--
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can be removed

@SamWilsn SamWilsn force-pushed the eip-call-flow-control branch from 114bb1c to 9968288 Compare January 24, 2025 00:23
@github-actions
Copy link
Copy Markdown

The commit a269e9d (as a parent of d421328) contains errors.
Please inspect the Run Summary for details.

Comment thread EIPS/eip-7867.md Outdated

The following subsections are modifications to the API endpoints from EIP-5792.

If a request does not match the schema defined below, the wallet MUST reject the request with an error code of 0 <!-- TODO -->.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i would prefer to create a params/constants table and refer them by their param/constant name here. brings it out as well as confine the TODO to a particualr section.

similarly with other TODOS

@g11tech
Copy link
Copy Markdown
Contributor

g11tech commented Jan 29, 2025

small nit and linter/markup fixes required

@lukasrosario
Copy link
Copy Markdown
Contributor

any particular reason this isn't an ERC @SamWilsn ? other capabilities are ERCs and 5792 technically does specify capabilities should be ERCs

Comment thread EIPS/eip-7867.md
Comment on lines +189 to +191
Strict atomicity is simply naming the default behaviour of EIP-5792: calls
within a single batch MUST be contiguous and applied atomically (or the batch
rolled back.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is effectively atomicBatch right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep!

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can I pitch a more explicit naming for atomicity
strict -> transaction
loose -> bundle
none -> none
I think this more clearly states what the app is requesting

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I find those more clear? What is a bundle? They also seem tied to particular implementations. I can imagine a multisig where each signature is a single transaction and only the last one executes the calls. You'd have multiple transactions, applied atomically.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think in that example I would only expect the last transaction to show up in the result (the signature transactions aren't really relevant to the app's request).

Fair that it's still not super clear. I guess I prefer these as it's more explicit about how the calls take place, i.e.
transaction = all in one transaction
bundle = in a bundle of transactions (Flashbots bundles as a reference), implying that transactions will be executed as a group, unless there's a reorg
none = no constraints

Comment thread EIPS/eip-7867.md

## Motivation

While the base EIP-5792 specification works extremely well for smart contract wallets, it does not allow the expression of the full range of flow control options that wallets can implement. For example, a dapp may only be submitting a batch for gas savings and not care about whether all calls are reverted on failure. A wallet may only be able to offer a limited form of atomicity through block builder backchannels, but that may be sufficient for a trading platform.
Copy link
Copy Markdown

@jakubuid jakubuid Feb 9, 2025

Choose a reason for hiding this comment

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

a dapp may only be submitting a batch for gas savings and not care about whether all calls are reverted on failure

Why wouldn't dapp care? What's the user flow in this case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Something like a token dispersement or several unrelated swaps. For example, I could be swapping several ERC-20 tokens into ETH. I just want as much of that ETH as possible, and I'll resubmit any failed swaps.

Comment thread EIPS/eip-7867.md Outdated
"data": "0xfbadbaf01",
"capabilities": {
"flow-control": {
"on-failure": "continue"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

what exactly is a wallet supposed to do in this case when the flow fails? what does continue mean? like to continue with the execution of the next calls? what if there's only one call in the array?

Copy link
Copy Markdown
Contributor Author

@SamWilsn SamWilsn Feb 9, 2025

Choose a reason for hiding this comment

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

Hopefully that's defined well enough later in the document (and let me know if it isn't), but a failed call with "on-failure": "continue" is just skipped, and the next call is executed.

Comment thread EIPS/eip-7867.md Outdated
Comment on lines +281 to +282
* MUST reject (with error code 0<!-- TODO -->) batches containing unsupported
`on-failure` modes.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We should rather set some default mode instead of forcing a wallet to reject such a batch. The reasoning is that on mobile devices MUST reject indicates that the wallet should reject such request immediately which is bad UX. Imagine a mobile wallet in the background that is triggered by a dapp aka it receives the batch request, a wallet is put to the foreground and immediately redirects back to a dapp without any information to the user. It should rather default to some mode and continue the flow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We should rather set some default mode instead of forcing a wallet to reject such a batch.

This is unacceptable behaviour. If the dapp requests a mode, it has to get that mode. Imagine asking for "rollback" and getting "continue". That could be catastrophic.

Imagine a mobile wallet in the background that is triggered by a dapp aka it receives the batch request, a wallet is put to the foreground

Does the wallet need to be in the foreground to reject the request? If so, how does the UX flow work for unsupported RPC endpoints, like for example eth_signTransaction on MetaMask? This doesn't seem unique to just this proposal.

immediately redirects back to a dapp without any information to the user

The standard doesn't say anything about not displaying information to the user. The wallet is free to display a message to the user before redirecting back to the dapp.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I meant more like the scenario where the dapp requests the mode, but the wallet doesn't support that mode. The proposal suggests the rejection, which is a bad UX on mobile, hence reasoning for some default behaviour that mitigates that.

Yes, on mobile, a wallet must be foregrounded to receive the request. So, in the MetaMask case (and not only), they support the CAIP-25 handshake, which defines the methods, chains, and events supported by a wallet, so dapp knows before sending the request if a given method is supported by a wallet or not. Hence, there's no problem with automatic rejection on mobile.

Now, when I'm writing this, I realized that the wallet could use the CAIP-25 handshake (sessionProperties) to define what modes are supported, so the dapp could only request those that the wallet supports.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@SamWilsn
I think it might be useful to add a section explaining how wallets can define flow-control capabilities via CAIP-25 that would mitigate the above. Something similar to the section in 7811

Comment thread EIPS/eip-7867.md Outdated
#### `wallet_sendCalls`

The wallet MUST reject `wallet_sendCalls` requests with error code 0
<!-- TODO --> where both:
Copy link
Copy Markdown

@jakubuid jakubuid Feb 9, 2025

Choose a reason for hiding this comment

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

As mentioned below, this creates a bad UX on mobile devices. We should rather default to one agreed behaviour to keep the user flow consistent instead of letting a wallet auto-reject such requests:
https://github.com/ethereum/EIPs/pull/9259/files#r1948151108

Comment thread EIPS/eip-7867.md
The returned `receipts` array:

* MUST NOT contain more than one receipt for the same transaction.
* SHOULD NOT contain receipts for transactions without a call from the requested
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why not MUST NOT? Is it allowed to add a receipt for a call that was not icluded in the batch? If yes, why, and what is the use case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I went with "MUST NOT" for things that would break/be unsafe, and SHOULD NOT for things that would be weird but not dangerous.

Comment thread EIPS/eip-7867.md Outdated
Comment on lines +155 to +157
"flow-control": {
"loose": ["halt", "continue"],
"strict": ["continue"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shouldn't this define on-failure flow control for call-scope and atomicity flow control for batch-scope?

Not sure how to interpret this part:

 "loose": ["halt", "continue"],
 "strict": ["continue"]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This snippet is saying the wallet supports on-failure modes of halt and continue when using loose atomicity, but only continue when using strict.

Comment thread EIPS/eip-7867.md
@SamWilsn SamWilsn force-pushed the eip-call-flow-control branch from a269e9d to ca6955a Compare February 27, 2025 16:54
@github-actions github-actions Bot removed the w-ci Waiting on CI to pass label Feb 27, 2025
Copy link
Copy Markdown

@azf20 azf20 left a comment

Choose a reason for hiding this comment

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

A couple of comments / questions.

Comment thread EIPS/eip-7867.md

## Motivation

While the base EIP-5792 specification works extremely well for smart contract wallets, it does not allow the expression of the full range of flow control options that wallets can implement. For example, a dapp may only be submitting a batch for gas savings and not care about whether all calls are reverted on failure. A wallet may only be able to offer a limited form of atomicity through block builder backchannels, but that may be sufficient for a trading platform.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it is worth mentioning the EOA use case (for 7702 laggards, whether chains or wallets).
I think it is also worth mentioning that while atomicity might be a hard requirement for some use cases (particularly Defi), for others it is not important, and this allows those apps to benefit from 5792 as well. Also notably approve-transfer is currently non-atomic, and improving that UX is generally a priority.

Comment thread EIPS/eip-7867.md
"atomicity": {
"enum": ["strict", "loose", "none"]
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

why not allow setting onFailure at the top level to set the default?

Comment thread EIPS/eip-7867.md
Comment on lines +189 to +191
Strict atomicity is simply naming the default behaviour of EIP-5792: calls
within a single batch MUST be contiguous and applied atomically (or the batch
rolled back.)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can I pitch a more explicit naming for atomicity
strict -> transaction
loose -> bundle
none -> none
I think this more clearly states what the app is requesting

Comment thread EIPS/eip-7867.md

A rollback is informally defined as "causing no meaningful changes on chain." A
rolled back batch only makes gas accounting and bookkeeping (eg. nonce)
changes. In other words, a rollback is the default behaviour of EIP-5792 when
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think it's worth calling out that with this EIP the default is strict / rollback (maybe not in this spot, but mentioning because it's alluded to here)

Comment thread EIPS/eip-7867.md
changes. In other words, a rollback is the default behaviour of EIP-5792 when
a call fails.

#### Critical Calls
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't see critical defined in the JSON schema?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm defining critical here so I can use:

  • "critical call" as short-form for call with "onFailure": "rollback" and;
  • "non-critical call" as short-form for the other modes.

Comment thread EIPS/eip-7867.md

* MUST treat a missing call-scope `flowControl` capability as equivalent to
setting `onFailure` to `rollback`.
* MUST treat a missing call-scope `onFailure` mode as equivalent to `rollback`.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think this is another argument for request-level onFailure settings - as an example I don't think loose and none are necessarily capable of rollback?

Comment thread EIPS/eip-7867.md
provide for any reason other than user rejection.
* Wallets supporting `strict` but not `loose` SHOULD NOT reject `loose`
batches and SHOULD instead upgrade the request to strict atomicity.
* Note that a batch with exactly one call _always_ satisfies the requirements
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For such calls any specification of flow control capabilities is effectively ignored, as it's necessarily strict / rollback?

Comment thread EIPS/eip-7867.md
batch.
* MUST contain exactly one receipt capturing each successful call.
* Multiple calls MAY be captured in one receipt, but the successful
execution of one call MUST NOT be captured by multiple receipts.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

is it even possible for a successful call to be captured by multiple receipts?

Comment thread EIPS/eip-7867.md
* `[(successful A, successful B)]`
* `[(successful A), (successful B)]`
* `[(successful A, unsuccessful B), (successful B)]`
* `[(unsuccessful A), (successful A), (successful B)]`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

how are unsuccessful calls represented? obviously the receipt as a whole has a status, but you can have failed calls in a successful receipt (requiring tracing to track down what actually happened) - and I don't see where in the call result it's identified one way or the other

Comment thread EIPS/eip-7867.md Outdated
{
"0x1": {
"flowControl": {
"none": [ "rollback", "continue" ]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

how do you rollback in none?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe the options should be halt and continue. Right @SamWilsn?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It would be quite weird to have none + rollback...

@eth-bot eth-bot enabled auto-merge (squash) March 12, 2025 08:33
Copy link
Copy Markdown
Collaborator

@eth-bot eth-bot left a comment

Choose a reason for hiding this comment

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

All Reviewers Have Approved; Performing Automatic Merge...

@eth-bot eth-bot merged commit c1e8ebe into ethereum:master Mar 12, 2025
1 check passed
Copy link
Copy Markdown

@KristijanSajenko KristijanSajenko left a comment

Choose a reason for hiding this comment

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

Gg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c-new Creates a brand new proposal e-consensus Waiting on editor consensus e-review Waiting on editor to review s-draft This EIP is a Draft t-interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants