Title: EIP_5792___Wallet_Function_Call_API
Category: EIPs

Author: moodysalem
Date: 2022-10-18T17:31:17.058Z

Thread to discuss EIP-5792

Author: moodysalem
Date: 2022-10-18T17:41:13.644Z

Re @SamWilsn:

I don’t like this design. It doesn’t force interoperability between wallets. A bundle created with WalletA may or may not be usable with WalletB. I would suggest either:

I might be misunderstanding the comment, but I don’t think interoperability between wallets of a specific bundle identifier is a specific goal of this (that is, if you have both Rainbow and Metamask with the same EOA imported, you should not expect dapps to have consistent transaction UX between connections of the two). It is assumed that each wallet will have its own address that has its own namespaced bundle identifiers

Author: SamWilsn
Date: 2022-10-18T20:21:51.797Z

Nope, you’re understanding it correctly. If I have an EOA today, I can freely switch between wallet applications with no drawbacks. As a user, I can’t support a standard that restricts that freedom (though as an EIP Editor, I can’t stop the proposal.)
Is it that difficult to standardize bundle identifiers?

Author: moodysalem
Date: 2022-10-18T22:11:39.950Z

SamWilsn:

As a user, I can’t support a standard that restricts that freedom


I agree that users should have mobility of their EOA between wallets. Both wallets should be able to import previous transaction history based on just the account.
For dapp interfaces, e.g. Uniswap interface, this EIP should have no impact on the transaction history UX as long as you don’t connect to a different wallet with the same address while a transaction is still pending. It seems like an edge case for a user to switch wallets for the same EOA while an interaction is pending.



 SamWilsn:

Is it that difficult to standardize bundle identifiers?


It would not work for the dapp to specify the identifier for the bundle, because that could only be stored in the connected wallet, and would not sync between apps.
You could use the hash of the message bundle, but when switching from wallet app A to wallet app B, wallet app B won’t know the preimage of the bundle and cannot query it from anywhere (i.e. it cannot query it from a JSON RPC as it can do with a transaction hash).

Author: SamWilsn
Date: 2022-10-18T23:00:48.722Z

moodysalem:

It seems like an edge case for a user to switch apps for the same EOA while an interaction is pending.


I use a different mobile wallet from my browser wallet. I don’t think it’s that inconceivable.



 moodysalem:

It would not work for the dapp to specify the identifier for the bundle, because that could only be stored in the connected wallet, and would not sync between apps.


Could it not be embedded in the bundle itself?



 moodysalem:

You could use the hash of the message bundle, but when switching from wallet app A to wallet app B, wallet app B won’t know the preimage of the bundle and cannot query it from anywhere (i.e. it cannot query it from a JSON RPC as it can do with a transaction hash).


Hm, and I guess the bundle might not have a tx.origin of the EOA itself (say for 4337 style bundles.) We are defining a new standard here, so we could make a new RPC endpoint on clients that deals with transaction bundles, if you’re interested in going that route.

Author: moodysalem
Date: 2022-10-19T01:36:02.092Z

SamWilsn:

I use a different mobile wallet from my browser wallet. I don’t think it’s that inconceivable.


In this case you’re using two different browsers, so the dapp doesn’t remember your transaction across the two contexts anyway–it’s stored in the window.localStorage for Uniswap interface, which isn’t synchronized across devices.

Could it not be embedded in the bundle itself?

Yes, you can put the dapp-selected identifier in the bundle, but that bundle + ID is not synced to other wallets, so other wallets won’t know what function calls that dapp-selected bundle identifier corresponds to when queried about bundle status.

Hm, and I guess the bundle might not have a tx.origin of the EOA itself (say for 4337 style bundles.) We are defining a new standard here, so we could make a new RPC endpoint on clients that deals with transaction bundles, if you’re interested in going that route.

I think this is purely a wallet JSON RPC method; it requires no P2P networking and no information about the state of the network. It’s just giving the dapps a better way to communicate with wallets about bundles of function calls that actually represent an action (e.g. approve and swap) rather than individual transactions.

Author: sbacha
Date: 2022-11-01T16:40:43.722Z

why no GraphQL support?

Author: rmeissner
Date: 2022-11-01T18:52:23.362Z

SamWilsn:

Is it that difficult to standardize bundle identifiers?


I would also add that the fact that smart contract wallets would handle differently to eoa based wallets might make this even harder.
for example for an eoa a bundle of multiple calls might result in multiple transactions, but for most smart contract based wallets that would only be 1 transaction. But for most smart contract based wallets the tx hash is calculated differently (e.g. the Safe uses a EIP-712 based hash). All of this makes it harder to create a standard for the bundle identifier.
Harder doesn’t mean impossible, but I don’t think it is necessary for this EIP and could be handled in a follow up EIP to this one.

Author: rmeissner
Date: 2022-11-01T18:57:53.472Z

Just as a general reference:
There has been a similar proposal with discussion that can be found here

Author: rmeissner
Date: 2022-11-01T18:58:45.010Z

Also could you elaborate why “function call” was used for the rpc name? For me “call” implies a non-state-changing operation, which is kind of confusing for this rpc.

Author: moodysalem
Date: 2022-11-03T19:16:06.896Z

Open to name suggestions, just gave it the best name I could think of that wasn’t overloaded (message is too ambiguous, bundles sounds like flashbots and needs qualifiers) but I think call is not usually meant as staticcall in most contexts.
Separately, I’m slightly concerned with the additional ‘optional’ qualifier in the current specification, perhaps that should be handled at the smart contract level. And anything more complex also, e.g. a dependency graph of function calls, should be expressed in the function that is called.

Author: rmeissner
Date: 2022-11-04T08:43:54.370Z

moodysalem:

but I think call is not usually meant as staticcall in most contexts.


Agree that this is the semantic on contract/evm level. My comment was more related to RPC level (e.g. eth_call vs eth_sendTransaction). I mean in the end it is just a name … so not the most important thing :P.
The only thing that for me in the name is important (and already is the case) is the wallet_ namespace 
Personally I think there are 2 important points to push this EIP forward:

Get the right people involved


Wallet developers (e.g. add MM, Rainbow and Argent)
SDK developers (e.g. WalletConnect, Ethers, Web3js and co)
Some dapp developers (i.e. CowSwap and 1Inch are quite cooperative)


Align on the return type


As mentioned before, I don’t think all the details have to be listed here, but I think it makes sense to have a plan how to move this forward. There will be many devs asking the same questions as @SamWilsn.
I think a uri schema based id would make sense. E.g. safe:tx:<some_hash> or evm:tx:<normal_tx_hash>. This way it is easy to extend this (can be defined in separate EIPs) and could even be backwards compatible.

Author: zemse
Date: 2022-11-14T10:05:11.829Z

What is the best way to know whether the connected wallet supports batching? I assume it will need a try-catch based on the following text in the EIP.

Three new JSON-RPC methods are added. Dapps may begin using these methods immediately, falling back
to eth_sendTransaction and eth_getTransactionReceipt when they are not available.

Knowing in advance whether a wallet supports batching can enable the frontend to show different UI. E.g. if batching not supported, Uniswap’s frontend shows both “Approve” and “Swap” buttons, but if wallet supports batching, just a “Swap” button can be shown.
What should be the behaviour of wallet_sendFunctionCallBundle with empty calls array? Would it fail or provide an id? (For check if RPC method is supported by wallet).

Author: rmeissner
Date: 2022-11-14T12:30:07.634Z

zemse:

Knowing in advance whether a wallet supports batching can enable the frontend to show different UI


I agree. It probably makes sense to have a separate rpc to get wallet capabilities. This could also be used for other rpc methods (e.g. related to signing; does a wallet support eip-712, etc.).
Should this be part of this eip or would it make sense to create a separate one for that?

Author: moodysalem
Date: 2022-11-14T23:14:12.664Z

rmeissner:

Should this be part of this eip or would it make sense to create a separate one for that?


I would vote separate as it needs to support this and other RPCs, but also shouldn’t be specific to wallets. Could just be a generic JSON RPC introspection endpoint, maybe returning an OpenRPC compliant response. I’ve also had cases where I was curious whether a particular RPC endpoint supported an RPC (e.g. eth_getProof support is not well documented)
But until such an endpoint exists, I think it’s a good carrot for adoption for dapps to just call eth_sendTransaction multiple times in its error handler. If dapps have to support different flows depending on wallet implementation, you still end up with the complex branching in the (single digit number of) dapps that support batch transactions for account abstracted wallets today. However this might break existing wallets if one call is required by a subsequent call, as the second eth_sendTransaction may be expected to fail without accounting for the first.

Author: moodysalem
Date: 2022-11-14T23:28:21.580Z

zemse:

What should be the behaviour of wallet_sendFunctionCallBundle with empty calls array? Would it fail or provide an id? (For check if RPC method is supported by wallet).


calls has a minItems of 1, implying that this should revert as a request validation error.

Author: SamWilsn
Date: 2022-11-16T19:01:52.191Z

I’d really like to see an option to specify the atomicity level of a bundle.
For example:


"atomicity": "none" → Stop on first failed operation. Operations successfully executed so far MUST NOT be reverted.

"atomicity": "loose" → If any operations fail, none of the operations should happen (they should either revert or not appear on-chain.) This could be implemented for EOAs with flashbots. May lose atomicity in the face of reorgs.

"atomicity": "strict" → If any operations fail, all operations MUST either revert or never appear on-chain. Must remain atomic in the face of reorgs.

If the wallet is unable to satisfy the requirements, it should fail the RPC request with a well known error.

Author: dror
Date: 2022-11-16T19:40:18.571Z

SamWilsn:

"atomicity": "strict" → If any operations fail, operations MUST revert


This mode is possible when working with contract wallets, but not with EOA.
For this API to be usable, it should have broad support for different wallets.
Also, a helper library (e.g. a wrapper provider) should be provided to provide this API on top of existing wallet API.
This provides both a reference implementation, and also an easy way for apps to work with providers whether they support the new API or not.

Author: SamWilsn
Date: 2022-11-16T19:55:47.220Z

dror:

This mode is possible when working with contract wallets, but not with EOA.


Exactly. Wallets that don’t support a particular atomicity level should fail the RPC request.



 dror:

For this API to be usable, it should have broad support for different wallets.


While I don’t disagree with you, I think for this API to actually get used in dapps, it needs to offer more than what you can do with plain JSON-RPC batching. I don’t think “indicating to users that a batch of operations is logically a single chunk” is enough for dapps to write custom code for it.
Pretty sure "atomicity": "strict" is already supported in smart contract wallets today though, so it would be nice to expose to dapps in a consistent way. It’s possible to add support for this to EOAs as well, so if something like that ever happens, they’ll be able to implement this too.

Author: yoavw
Date: 2022-11-16T23:04:33.486Z

I second @SamWilsn on "atomicity".  It makes sense for the dapp to specify whether it’s a nice-to-have batching for saving gas (so none), frontrunning/sandwiching protection (that would be loose), or an actual security reason (strict).
Most contract wallets, whether 4337 or not, as well as wallets using an EIP 3074 invoker, can support all three (and in practice they’ll always provide strict because they’ll batch everything to a single transaction).
EOAs would return an error if strict, use Flashbots (or any other trusted mev-boost building service) for loose, and normal mempool transactions for none.
Dapps should only use strict when there’s a real reason, since some wallets won’t support it.
As for communicating the identifier when switching wallet (or using a 3rd party explorer to look at the bundle), I wonder if it would make sense to encode it on-chain in the 1st transaction of there’s more than one.  One byte of calldata may be enough.  Contract wallets will always use one transaction, so no need to encode anything.  If from is an EOA, then we can assume consecutive nonces and therefore we only need to know the number of transactions in the bundle.  A uint8 appended to calldata of the first transaction should be enough for all practical purposes.
The 2nd wallet will then decode the 1st transaction, parse the redundant byte, and check for the next N-1 transactions (either on-chain or in mempool).
The caveat (aside from paying gas for the additional calldata byte) is that the 2nd wallet can only parse it if it knows the call’s signature so that it can identify the appended byte as a non-parameter.
I’m not sure it’s worth the hassle, and adding an on-chain component (however small).  Just seems like an easy way to identify bundles across wallets.

Author: moodysalem
Date: 2022-11-18T15:06:05.121Z

yoavw:

Dapps should only use strict when there’s a real reason, since some wallets won’t support it.


My concern with the atomicity feature is that dapps will build things with this API that only work for the strict level of atomicity, which is bad for users of wallets that do not support it, i.e. the majority of Ethereum users today
And anything that is strict can probably be made into none by just architecting the contract differently–I can’t think of a counterexample to this point. So there’s no reason to actually require strict.
strict is also a bit funky when the combined calls require more than block gas limit and must be sent as multiple transactions. Maybe there should be an additional specification that the request should reject if the wallet cannot make all the calls in a single block, or maybe we want to support that use case of many calls that must be made in separate blocks

Author: SamWilsn
Date: 2022-11-18T20:25:38.517Z

moodysalem:

My concern with the atomicity feature is that dapps will build things with this API that only work for the strict level of atomicity, which is bad for users of wallets that do not support it, i.e. the majority of Ethereum users today


So those dapps will either struggle to get adoption from current Ethereum users, or build a fallback. I think it’s better to standardize these features so that dapps using them will automatically support wallets adding atomicity instead of relying on bespoke integrations.
Imagine I wrote a dapp today that needed strict atomicity, and I write code that supports Gnosis Safe using their API. I die and obviously am unable to continue updating my dapp. Some time passes, and we finally get EIP-3074. Now all wallets can implement support for strict atomicity, but my dapp is stuck only supporting Gnosis Safe.



 moodysalem:

And anything that is strict can probably be made into none by just architecting the contract differently–I can’t think of a counterexample to this point. So there’s no reason to actually require strict.


For sure! I’m thinking of scenarios like complex DeFi arbitrage or rescuing NFTs from hacked accounts, where the transaction sender doesn’t have control over what they’re interacting with.



 moodysalem:

strict is also a bit funky when the combined calls require more than block gas limit and must be sent as multiple transactions.


If a wallet can’t ensure the operations are performed atomically (because it’s an EOA, because of the gas limit, or for any other reason), the RPC call must fail.

Author: moodysalem
Date: 2022-11-20T17:54:26.636Z

SamWilsn:

Imagine I wrote a dapp today that needed strict atomicity, and I write code that supports Gnosis Safe using their API. I die and obviously am unable to continue updating my dapp. Some time passes, and we finally get EIP-3074. Now all wallets can implement support for strict atomicity, but my dapp is stuck only supporting Gnosis Safe.


In absence of the strict atomicity request parameter, wouldn’t you build your dapp and contracts to work for all wallets, i.e. using the default none behavior? In that case, all wallets would support it on day 0, and the UX for gnosis safe would be unchanged. The atomicity request parameter enables dapp developers to build dapps that are only supported by certain kinds of wallets, even though they could just build it for all wallets without sacrificing anything.



 SamWilsn:

For sure! I’m thinking of scenarios like complex DeFi arbitrage or rescuing NFTs from hacked accounts, where the transaction sender doesn’t have control over what they’re interacting with.


I think this is out of scope for this EIP, for a bunch of reasons in no particular order:

These use cases have more to do with using a private relay than bundling function calls
E.g. in cases where a rescue does require multiple function calls in a single transaction, and there is no authorization, you can do that in the constructor of a contract deployment (no bundling necessary)
This is a bespoke use case that is usually handled with scripting
The mempool and sequencing behavior is closely related to the underlying blockchain, whereas this API is meant to abstract those details away from the dapp developer as much as possible
The wallet can have a toggle to use a private relay without any change to the RPC interface




 SamWilsn:

If a wallet can’t ensure the operations are performed atomically (because it’s an EOA, because of the gas limit, or for any other reason), the RPC call must fail.


This does push a lot of complexity onto the dapp in the rare case that the set of function calls costs more than block gas limit. It’s nice for dapp developers to not have to worry about the total size of their batch. Wallets will also have different amounts of overhead for batch function calls, so dapps cannot predict the actual cost of sending the entire batch of function calls. But I wouldn’t be strongly opposed to adding a constraint that the RPC fails if it would be impossible to include all the function calls under the block gas limit.

Author: SamWilsn
Date: 2022-11-21T06:42:38.417Z

moodysalem:

In absence of the strict atomicity request parameter, wouldn’t you build your dapp and contracts to work for all wallets, i.e. using the default none behavior?


It’s possible today to build a dapp that relies on strict atomicity, but the specifics of how to do that are unique to each smart contract wallet. I’d really like to see some standardization there.



 moodysalem:

build it for all wallets without sacrificing anything


There are zero dapps that could be built with strict atomicity that could not be built without it?



 moodysalem:

It’s nice for dapp developers to not have to worry about the total size of their batch.


Agreed! For the "atomicity": "none" case, I think it’s fine to split the batch over multiple blocks.

Author: moodysalem
Date: 2022-11-21T15:13:28.921Z

SamWilsn:

There are zero dapps that could be built with strict atomicity that could not be built without it?


I believe so. Even if a smart contract is not EOA-friendly, it can always be wrapped. For example, consider an ERC20 without an #approve function. To spend this token you would have to call #transfer and then atomically call another contract. You can work around this: deploy a contract to hold the tokens, transfer the tokens to that contract, and then execute calls from the holder contract.
For every example I can think of, there is a different pattern that does not require atomicity across the function calls. It might be possible to formally prove this point. Assuming the point is true, I don’t think there’s any reason for a dapp developer to build a feature that requires it, so the request parameter only acts as a footgun.

Author: DrewF
Date: 2022-11-30T22:18:26.678Z

While it seems very likely that a contract that enforces strict atomicity can be constructed for every scenario, there’s room for dapps to use the strict flag, even if it does fail.
Dapp developers may want to optimistically enforce a strict bundle, and upon failure, ask the user to acknowledge the risk they will take by downgrading to ‘loose’ or no atomicity. If a Dapp presents a user with one button to click and sign multiple transactions, it seems like pretty poor UX if part of the call reverts. This is especially true for EOA users, whose current expectation is that each signature from their wallet results in one (atomic) transaction.



 moodysalem:

For every example I can think of, there is a different pattern that does not require atomicity across the function calls. It might be possible to formally prove this point. Assuming the point is true, I don’t think there’s any reason for a dapp developer to build a feature that requires it, so the request parameter only acts as a footgun.


Instead of building an on-chain abstraction over every contract in the Dapp, developers can leverage account abstraction to create one-signature contract compositions for users (including for contracts that the dapp developer was unaware of, provided the user can import an ABI). Optimistically, the developer can request the bundle using "atomicity": "strict", then fall back to "loose" or "none" along with a warning and explanation that the atomic composition implied by the single signature for the queued transactions will be degraded.

Author: moodysalem
Date: 2022-12-01T18:13:17.418Z

DrewF:

Dapp developers may want to optimistically enforce a strict bundle, and upon failure, ask the user to acknowledge the risk they will take by downgrading to ‘loose’ or no atomicity.


Can you share an example of when you’d be ok with loose or no atomicity even though you wanted strict?



 DrewF:

including for contracts that the dapp developer was unaware of, provided the user can import an ABI


This case sounds like it’s not known by the dapp whether atomicity is needed or not, but that’s a really advanced user and the user should specify the atomicity requirement in this case… but wouldn’t they just not send these transactions separately if their wallet doesn’t support it or do some other workaround? Seems like a slightly convoluted use case AFAICT

Author: DrewF
Date: 2022-12-01T19:39:18.672Z

The most concrete use case that came to mind was a block explorer with a transaction queue. If it provides users visiting with a way to visit a few contracts and build a set of transactions to execute, a naive user would probably expect the batch to execute together, especially with only one wallet signature for the full queue, and so the default behavior should be strict atomicity.
I agree that the ‘loose’ atomicity is a rather weak construction, as it encourages users to route batches to private mempools, and feels like an abstraction leak that may change with underlying things like AUTH/AUTHCALL or single-slot finality. I’d be happy to hear more arguments in it’s favor, but having a bollean flag for enforcing all-or-nothing execution of a bundle seems like a good abstraction of underlying wallet mechanics for developers of tools like block explorers or general purpose contract interfaces.



 moodysalem:

but that’s a really advanced user and the user should specify the atomicity requirement in this case


I’m operating under the assumption that as the EVM gets used by more people, competent early adopters will continue using EOAs, but new/less advanced users will onboard to accounts with features like atomic batching. I think we should make it easy for dapps to cater to them, and warn EOA users that “the bundle may only succeed in part or be split up, would you like to send the transactions anyway”.
Essentially I’d like the line in the EIP

MAY revert all calls if any call fails

to instead be

MUST revert all calls if any call fails when "atomic": "true"

Author: moodysalem
Date: 2022-12-10T20:17:09.750Z

DrewF:

and so the default behavior should be strict atomicity.


For something like complex transaction building (e.g. furucombo) you usually want to involve a smart contract to introduce logic between the calls (e.g. all or nothing, these 2 calls are optional, take output of this call and pass as input to another call). Furucombo still greatly benefits from this EIP because the spending approvals can be batched with the function calls you want to make. The one drawback is the calls do not come from the user’s wallet. But I’m not sure if support for that is really required for any meaningful transaction building use case.
I’m on the fence. I want this interface to be as narrow and abstract as possible so as to prevent dapps from building branching logic based on wallet capabilities, which either adds work for the dapp developer or excludes wallets. The “atomic” flag definitely leaks wallet implementation details to the dapp. But if people are strongly in favor of this change I’ll add it–I’m definitely more ok with atomic flag than 3 different levels of atomicity which feels even leakier.



 DrewF:

competent early adopters will continue using EOAs, but new/less advanced users will onboard to accounts with features like atomic batching


My two cents on this is I’d think early adopters will want account abstracted wallets for better security/recovery, or other features they offer. I myself am a user of a smart contract wallet, and many of my friends use gnosis safe for self custody. I’m not sure if that changes the calculus.



 DrewF:

Essentially I’d like the line in the EIP


Yup, makes sense, totally get what’s being asked for here.

Author: marc
Date: 2023-01-25T15:37:36.556Z

Hey everyone, wanted to add that we have added support for EIP-5792 for CANDIDE mobile Wallet. We are supporting the three methods:

wallet_sendFunctionCallBundle
wallet_getBundleStatus
wallet_showBundleStatus

Here’s our implementation for other wallet developers to reference:


github.com/candidelabs/candide-mobile-app








feat: support eip 5792



          Commit by
          

            andrewwahid
           - feat: support eip 5792



main ← feat/support_eip_5792








Documentation for dapp developers wishing to support bundle calls in their app, along with a codesanbox to start experimenting with. We wrote examples for Web3Modal and WalletConnect Standalone:



docs.candide.dev



Batch & Sponsor | Candide
Batch multiple actions into a single on-chain transaction, and sponsor gas for your users -- reducing costs and enhancing your app UX

Author: moodysalem
Date: 2023-01-30T22:24:10.896Z

rmeissner:

I agree. It probably makes sense to have a separate rpc to get wallet capabilities. This could also be used for other rpc methods (e.g. related to signing; does a wallet support eip-712, etc.).


In the absence of this method, does it make sense to add one to the EIP just for checking if this particular set of methods is supported? Reviewing the guide posted by @marc and thinking about this again, I can’t imagine implementing this in a mature dapp and falling back to multiple eth_sendTransaction calls as I originally proposed. There will need to be a transitional period where a dapp needs to support both existing wallet APIs well and the function call bundle API.
Such a method could look like: wallet_isFunctionCallBundleSupported with no parameters, returns true if supported and errors or returns false if not supported.

Author: marc
Date: 2023-11-08T10:49:01.586Z

I’d like to revive the discussion regarding the EIP as we continue our efforts to call for both wallet and dapps to integrate it.
Recently, we worked with PoolTogether to develop a more user-friendly interface for the no-loss donation use case. This involved a multi-step interaction process comprising 6 batch transactions, which included granting approval for the contract, depositing funds, and delegating winnings to another address. We didn’t encountered issues. Note that we built the frontend from the ground up to support exclusively batch transactions. There’s no way for an EOA to interact with it.
Net steps we will assist two dapps in integrating this EIP into their interfaces. Since these dapps already support the standard EOA workflow. We will be adding support for batch transactions if a smart wallet is connected. I will keep updates posted as they progress.

Author: SamWilsn
Date: 2023-12-16T02:25:51.576Z

After Tweeting with only a vague recollection of this discussion, I accidentally discovered another axis I think should be covered by the endpoint: what happens on failure in the none case. Here are all the options now:

"atomicity": "continue-on-fail" → Send all the transactions even if some fail.
"atomicity": "stop-on-fail" → Stop on first failed operation. Operations successfully executed so far MUST NOT be reverted.
"atomicity": "loose-revert-on-fail" → If any operations fail, none of the operations should happen (they should either revert or not appear on-chain.) This could be implemented for EOAs with flashbots. May lose atomicity in the face of reorgs.
"atomicity": "strict-revert-on-fail" → If any operations fail, all operations MUST either revert or never appear on-chain. Must remain atomic in the face of reorgs.

Author: JXRow
Date: 2024-03-27T01:26:58.707Z

This EIP is stagnant, is there anything wrong?
I’ve been working on atomic:



ERC-7638: Optimized Calls Encoding Wallets


    This ERC can use like ERC4377, but much simple, and cost less gas
  





Batch Calls JSON Schema EIPs


    Batch calls we use oftenly, like Approve then Swap, Approve then TransferFrom, user needs to confirm twice or more in wallet, we put the calls into a JSON, so that the wallet can deal the calls automatic in just one confirm. Here’s the JSON example: 
let json = {
        rpc: {
            name: 'Scroll_Alpha',
			url: 'https://alpha-rpc.scroll.io/l2',
			chainId: 534353
		},
        calls: [
            {
                to: '0x67aE69Fd63b4fc8809ADc224A9b82Be976039509',
                value: '…
  

Maybe I can help you

Author: bumblefudge
Date: 2024-04-04T07:09:45.481Z

marc:

I’d like to revive the discussion regarding the EIP as we continue our efforts to call for both wallet and dapps to integrate it.





 JXRow:

Maybe I can help you


Guys, we're so back.

A new PR bumped the status from stagnant to draft: EIPs#8361
And I also opened a PR of my own, #8396, trying to incorporate suggestions made in the 8361 comments and elsewhere, to continue the refinement.
Related PRs might be opening soon on capability and/or permissions expressions and discovery, so I’m hoping this stays “Draft” long enough to cross-reference other relevant drafts.

Author: SamWilsn
Date: 2024-04-11T18:08:47.887Z

Should this proposal specify the error response when two conflicting capabilities are requested in the same batch?

Author: bumblefudge
Date: 2024-04-11T22:40:23.832Z

In general, I’d be supportive of that because wallet_getCapabilities is defined here so its failure modes or expectations should be defined here, but this EIP only specifies one capabilities so I worry the burden of defining what might contradict with atomicBatch falls on the future EIP defining a second capability related enough to contradict it, wouldn’t it?
Were you thinking a strong fail (e.g. 1.)
a calling app MUST NOT use either capability if two returned capabilities are contradictory in ways defined by either capability's specification
, or a no-obligation (e.g. 2.)
a calling app MAY ignore the behavior specified by a returned capability if that capability is logically contradicted by another returned capability
?

Author: SamWilsn
Date: 2024-04-12T00:20:06.407Z

I was thinking something along the lines of:

If a wallet is unable to fulfill a request because it contains two or more incompatible capabilities, it MUST reply with an RPC error code of 7

Author: bumblefudge
Date: 2024-04-12T00:23:10.817Z

Oh, ok, you’re talking about if the REQUEST contains two capabilities that can’t both be granted at the same time, I’m talking about the RESPONSE being self-contradictory.
If the app asks for 2 caps that can’t both be granted at the same time, why throw 7 instead of just…picking one or none?  Isn’t a wallet allowed to grant any subset of the requested capabilities? If I were a wallet, I would simply reserve 7 for when it’s actually impossible, and pick my favorite of the two.

Author: SamWilsn
Date: 2024-04-12T03:06:37.013Z

why throw 7 instead of just…picking one or none?

I prefer to fail safely and predictably I guess

Author: bumblefudge
Date: 2024-04-12T03:17:44.923Z

Maybe i don’t understand what you mean by incompatible.  With each other?
If dapp requests “atomicBatch”:“true” && “atomicity”:“none”, are they contradictory?  Or are they just expressing that, in YoavW’s words, atomicity is “a good to have” but not tactical?
Or if they request “atomicBatch”:“false” and “atomicity”:“strict”, are you saying the wallet should be forced by the spec to assume the request is malformed and drop it for safety’s sake? I feel like how all future capabilities will interact is hard to define in advance, and “contradiction” feels pretty hard to spec out here IMHO (not discouraging you from continuing to try, I’m just not seeing the logic yet)

Author: SamWilsn
Date: 2024-04-12T15:06:17.194Z

I’m only suggesting that EIP-5792 pick an error code to use when the wallet refuses a request because of conflicting capabilities, regardless of what the capabilities are or why they are conflicting.

Author: bumblefudge
Date: 2024-04-12T17:37:45.313Z

SamWilsn:

an error code to use when the wallet refuses a request because of conflicting capabilities


Ah, OK, giving the wallet an optional way to express this specific fail-case would be great, I totally agree! I thought you were saying the wallet SHOULD or MUST return that error code if {hard-to-specify condition}.
I don’t see anything that maps to “contradictory/malformed-request” in the generic EIP-1193 error codes and in the CAIP-25 error codes 5000 is “unknown error” (at authorization-request level) and 5204 is “ambiguous/contradictory request” (having to do with overlapping CAIP-217 scope objects, i.e. CAIP-25-internal contradiction), which is probably the closest analogy to overlapping capability objects.

Author: marc
Date: 2024-04-22T20:23:35.511Z

The new changes in the naming are welcomed, and good we took the atomicity comments from Sam into consideration. Having the capabilities in separate ERCs is also a step in the right direction.

Author: dror
Date: 2024-04-28T10:21:51.192Z

One thing that is sorely missing from the specification, is a recommendation on the “atomicity”:
Trying to be “un-opinionated” on sending a batch leaves a lot of room for apps to hang themselves: e.g. an app sends a batch of 3 transactions through a “best effort” wallet, needs to handle all cases (that is, only 1, only 2, all 3) transaction succeeded - otherwise, the wallet can be left in limbo (or worse, in a vulnerable) state.
At a minimum, atomicity capability should be specified as SHOULD, while explaining the app has to understand and handle the consequences of sending a non-atomic batch.

Author: frangio
Date: 2024-05-29T00:24:55.783Z

wallet_sendCalls Example Return Value
The identifier can be any string. The only requirement is that for a given session, users should be able to call wallet_getCallsStatus with this value and expect a call-batch status to be returned.

The term “session” is not defined in the EIP and I don’t think there is a clear implied meaning. It would be great to provide more clarity on that.

Returning capabilities per chain id might be necessary, but in the case that a capability is globally supported for all chains, how is the wallet supposed to respond? Does it make sense to ask the wallet to enumerate all supported chains?

Author: frangio
Date: 2024-06-05T22:55:04.406Z

In the previous AllERCDevs call we discussed how this EIP opens an opportunity to solve a current UX pain point in Ethereum: the problem of displaying transaction parameters to users.
In eth_sendTransaction, the parameters are expressed as an opaque calldata bytestring. Ideally the wallet would show a detailed view of the transaction parameters the user is agreeing to, but there is no simple and robust way for wallets to decode calldata. One option is to rely on databases of function signatures, but function selectors are small and clashes are easy to find. Another option is to rely on verified source code and ABIs, but this currently depends on centralized providers, essentially on Etherscan. Function selector databases by extension also depend on those providers.
wallet_sendCalls has inherited the opaque data parameter. One idea that came up in the call was to specify the data for each call not as a bytestring but as a function ABI spec and the array of function arguments to be encoded by the wallet.
I think that would be very nice but is a relatively large departure from the current spec, which is currently already in Last Call, as well as a departure from eth_sendTransaction which might hinder adoption.
As an alternative, we could keep the EIP as is, with data as a bytestring, and use the capabilities mechanism to specify an ABI per target address so that the wallet can decode it. This is an improvement over the current state of things because the dapp already knows the ABI, it just needs to communicate it to the wallet.
A couple of things to note:

The mechanism should not be Solidity-specific. It should be possible to use different ABI formats and encoding/decoding procedures.
This mechanism would allow a dapp to provide a false ABI that could mislead a user as to what they’re signing. I’m not sure if this is a worse outcome than being shown opaque bytes. We may conclude that the wallet should check to see if the ABI has been verified, in which case we are back to relying on verification and the mechanism doesn’t really make sense. Curious to hear other’s opinions on this.

Author: shanejonas
Date: 2024-06-19T17:19:02.326Z

From some discussion in All Wallet Devs today:
MetaMask is working towards an MIP to support regular JSON-RPC batching (non-atomic) for EIP 1193


github.com/MetaMask/metamask-improvement-proposals








JSON-RPC Request Batching


main ← json-rpc-request-batching



          opened 07:12PM - 27 Mar 24 UTC




            jiexi
          



+140
-0






## Summary
This proposal aims to extend the MetaMask JSON-RPC API that is acces…sible via `window.ethereum.request()` to include support for batching requests. Batched requests would be processed in parallel by the wallet. All passthrough requests in a batch will be sent to the RPC endpoint in a batch. All requests requiring user confirmation will have results returned after user approval/rejection. Results will be returned as available and are not guaranteed to be in the same order as the respective requests. Introducing native support for request batching allows developers to improve Dapp efficiency and aligns the MetaMask JSON-RPC API closer to the [JSON-RPC 2.0 specification](https://www.jsonrpc.org/specification#batch).

Author: dbrans
Date: 2024-07-17T15:21:22.388Z

Hi,
Thank you for putting together this proposal!
Does EIP-5792 have considerations for disconnection between the dapp and wallet while a call is in progress (e.g., if the user goes offline for a few days or if the laptop battery runs out)? Specifically, does the dapp have a way of tracking the call in such cases? Is this seen as a potential problem, and if so, should it be addressed within this EIP?

Author: dbrans
Date: 2024-07-17T15:40:27.597Z

A suggestion: it would be helpful to clarify the benefits for dapps using wallet_sendCalls over eth_sendTransaction for sending and tracking individual transactions and not just batches. You could highlight simplified transaction tracking and better handling of transaction replacements.

Author: dbrans
Date: 2024-07-17T15:41:19.798Z

A quick question:
status: 'PENDING' | 'CONFIRMED';

Should we also include a status for indicating if a transaction was DROPPED or FAILED?
Thanks!

Author: rekmarks
Date: 2024-07-17T22:03:05.605Z

Since all of these methods are Ethereum-specific, I’m wondering if it wouldn’t be better if they were prefixed with eth_ instead of wallet_? eth_ is not merely for clients; eth_requestAccounts has been in production for 5-6 years (ref: EIP-1102).
Also, the specification mentions CAIPs, but did the authors discuss how to reconcile these methods with CAIP-25 and CAIP-27? For instance:

How should a dapp call wallet_sendCalls using CAIP-27?

Does the CAIP-27 chainId have to match that of wallet_sendCalls?

Author: antonydenyer
Date: 2024-07-30T14:23:02.974Z

One reason I think it should remain in the wallet_ namespace is that the wallet should decide how to proceed with this; there could be different options on different networks/wallets, etc.

Author: antonydenyer
Date: 2024-07-30T14:49:36.065Z

From a dapp and wallet perspective, you cannot perform a meaningful estimate gas on batch transactions when following/utilising the json rpc spec. Let’s say you have an approve and swap and wish to submit them as a batch. You can perform the estimate gas on the approval but not the swap. When you perform the estimate gas on the approval, it will fail with a revert.
Without something like eth_multicallV1, is there an expectation that the wallet will take care of it in a non-standard way?

Author: dror
Date: 2024-08-21T12:39:47.843Z

I can see that lately eip-5792 added a major change, which tries to make it cross-chain API.
While cross-chain wallet API might be useful, it is much more complex than moving the chainid field.
when handling cross-chain, the application must be aware of the different technical features of the different chains, like block times, gas payments, and even account addresses which might differ.
I suggest deffering cross-chain capabilities to a separate EIP.

Author: dror
Date: 2024-08-21T14:24:34.323Z

Are there any wallets and applications already using this api?
I think there are some points where the api is not fully specified.
atomicBatch - while there is such capability, there is no way for an app to require a batch to be atomic. Missing something like “requireBatch”, to imply the TX should be aborted if the wallet can submit a single batch.
wallet_getCallsStatus is very ambigous if calls can be non-atomic.
The top level “status” can’t describe partial completions (and in fact, I don’t see how app can take action after partial completion, except for indefinite wait, since it doesn’t have any other id to track those independent requests
wallet_showCallsStatus - cannot be used generically. Since the app has no way to define what information is shown to the user (if at all), it can’t use it unless the app already knows this wallet implementation and what information it shows.
gas not including gas at all leaves the apps unable to constrain calls in any way - unable to estimate the gas, and unable to limit max used gas.
At its present state, I don’t think the API is usable, let alone close to “final”.

Author: frangio
Date: 2024-09-05T02:39:47.710Z

dror:

atomicBatch - while there is such capability, there is no way for an app to require a batch to be atomic. Missing something like “requireBatch”, to imply the TX should be aborted if the wallet can submit a single batch.


I agree, I assumed this would be somewhere in the EIP but it isn’t.
The EIP says this:

gives developers the option to only submit batched calls if they are executed atomically

The only way that I can see this done with the EIP as specified is to get the capabilities and if atomicBatch is reported as “supported” then assume that batches are automatically atomic? This is not what I’d interpret from “supported”, which sounds more like it is supported if requested.

Author: SamWilsn
Date: 2024-09-18T17:24:02.849Z

From AllWalletDevs today, it looks like MetaMask (via @vandan) and WalletConnect are investigating/using these proposals for chain-specific method calls:

CAIP-25: Wallet Create Session JSON-RPC Method
CAIP-27: Wallet Invoke Method JSON-RPC Method

Seems relevant to the per-chain calls being specified here.

Author: JXRow
Date: 2024-09-29T06:54:57.684Z

I believe that making the encoding process of hex data an optional feature would greatly enhance wallet security. Users fall victim to phishing because the interaction process of the wallet pop-up window is generally incomprehensible. If this option were available, the wallet could analyze the risks involved in the interaction and then alert the user.

Author: naivesheep
Date: 2024-12-04T21:14:35.244Z

Hi, I have a few concerns with respect to the draft of this EIP.
First is that it seems like capabilities as returned by wallet_getCapabilities are per-chain, but capabilities as specified for wallet_sendCalls is chain agnostic. Since a wallet_sendCalls request can include calls to multiple chains, I think it would make more sense to move the capabilities parameter into the call structure so that each call can specify its own capabilities based on what its chain actually provides.
My second concern is that some functionality such as the atomicBatch capability might be provided by default on all every chain a wallet supports, which could be numerous, especially for smart contract wallets. So I think it also makes sense to add a special wildcard * in place of the chain ID for those cases where a capability is universally available.
Lastly, are there any wallet implementations of this specification in the wild at this moment? It seems like this EIP addresses a missing piece of the UX puzzle, but it sounds like it’s been in development for a couple of years so it would be good to know if it’s on the road to being finalized.

Author: chaitanyapotti
Date: 2025-01-06T21:18:01.182Z

In the latest version of the eip, the text describing wallet_sendCalls doesn’t match the RPC specification.
Requests that a wallet submits a batch of calls. from and chainId are top-level properties rather than per-call properties because all calls should be sent from the same sender and on the same chain
It must change instead to make chainId not a top-level property.

Author: azf20
Date: 2025-02-25T16:01:50.296Z

This EIP is more relevant than ever, particularly with the advent of EIP-7702.
As @chaitanyapotti and @naivesheep point out, the text no longer matches the specification.
For what it’s worth, I think adding chainId at the “call” level rather than the “request” level introduces quite a lot of complexity, and I am not sure what the upside is. Are there motivating use cases which might help?
I think there is value in standardising the identifier, even if it’s just based on a hash of the calls plus some salt. I don’t think it’s a hard requirement that any wallet needs to be able to fetch the status - in the current setup, wallets already only see transactions initiated by other wallets once they’ve landed onchain as a txhash (some may monitor the mempool, but I don’t know how much that works). But I do think it is helpful if the identifier is somewhat predictable.
A salt / nonce-equivalent might also prove useful for wallets - the current specification doesn’t seem to have many guardrails preventing accidental replays / allowing for idempotency, and it might be useful if the wallet has an easy way to say “you already submitted this bundle” (of course sometimes you might want to repeat the same calls)
In terms of callStatus, I don’t think the current spec is that helpful. Why wouldn’t we specifically report the receipt per call, something like:
type GetCallsResult = {
  status: 'PENDING' | 'CONFIRMED';
  calls: {
    call: {
      to?: `0x${string}` | undefined;
      data?: `0x${string}` | undefined;
      value?: `0x${string}` | undefined; // Hex value
      chainId?: `0x${string}` | undefined; // Hex chain id
      };
    receipt: `0x${string}` | undefined; // Note that multiple calls might have the same receiptId
  }[]
  receipts?: {
  // receipt fields
  }[];
};

Relatedly, I think there should be more specification of the expected failure behaviour:

If a call fails in simulation, should the bundle be submitted?
What happens if one of the calls fails onchain? (e.g. if it reverts / runs out of gas)
I think in either case we need a “Status” to handle those cases.

I don’t really see the value of the showCallsStatus, I think that wallets should already be displaying the in progress calls in their existing UI, and I think if the GetCallsResults returns the info per call that gives apps enough to provide a meaningful UI themselves.
There is some discussion in the thread already around atomicity, I think it’s reasonable to provide this is a capability, but I note that the other capability example in the spec (paymasterService?) is maybe more of a “hint” than a requirement, so I think it’s worth clarifying where capabilities in sendCalls fall on that spectrum.
A final note is that “version” appears a couple of times in the spec, I think a wallet should also be able to specify what “version” of the spec it supports (maybe that is part of capabilities?)
I am excited to see innovation at the app / wallet interface, so would love to see progress on this EIP!

Author: azf20
Date: 2025-02-26T18:40:49.600Z

Following up on the above, the current EIP text is outdated and the latest thinking & discussion is in this open PR: github dot com/ethereum/EIPs/pull/8826 [no permission to post links]

Author: SamWilsn
Date: 2025-02-26T21:58:36.055Z

github.com/ethereum/EIPs








Update EIP-5792: Propose changes to EIP-5792


ethereum:master ← eth-infinitism:eip-5792-proposal



          opened 08:35PM - 25 Aug 24 UTC




            forshtat
          



+120
-83






List of changes proposed in this PR and their motivations:

1. Rephrase "The i…tems in the `calls` field are only those that are shared by all transaction types" and "method only returns a subset of the fields that `eth_getTransactionReceipt` returns, excluding any fields that may differ across wallet implementations".

There is a rapidly growing list of transaction types, and the definition of the "shared by all" can become confusing.
Specifically, most transaction fields are removed in RIP-7560 transaction type which is part of the Account Abstraction roadmap.

2. Add optional 'capabilitiesData' field to individual 'calls' entities.

It seems likely that more advanced capabilities will need to provide some data on a per-call basis. One example could be an "optional flag" capability that would allow a Smart Contract Wallet to proceed with the batch in case of a revert, which would otherwise default to requiring success from all calls. Whether this particular capability is needed or not, it serves as an example of why such an option might be needed in the future.

3. Specify that an unsupported 'capability' cannot be ignored and the operation must be rejected.

I did not see it in the text anywhere, and ignoring data provided in the capabilities field is obviously extremely dangerous.

4. Add 'chainId' back to the 'SendCallsParams'.

For now, it is defined as optional, but probably shouldn't be. This has been debated lately and I don't know what the conclusion is.

5. Specify that the 'identifier' must be a 32 byte hex.

One reason is that "any string" seems to be too vague of a definition for an ERC. What about "", "ለከበሩጓደኛመርህመንገድይሆናል", or "😎🤏🕶😳", are these strings okay?
Also, in other programming languages it could be more convenient to use the same identifier type as for transactions, blocks and all other things in Ethereum. If there is a motivation for leaving it as "any string", please at least specify it in the ERC.


6. Added 'capabilitiesData' object to the 'wallet_getCallsStatus' response.

It seems very plausible that 'capabilities' will need to provide some additional information to the response. This was previously impossible, which could lead to wallets creating non-standard ways of querying that information.

7. Made the 'receipts' field requirements stricter.

These rules were probably implied anyway, but now they are explicit.

8. Rename 'status' to 'batchStatus'

There is a 'status' field in each 'receipt', which is a hex string. Having another 'status' field, that is not of the same type, appears to be confusing.

9. Specified 5 separate 'batchStatus' values

It seems like the previous two values did not cover the entire set of possible 'sendCalls' outcomes. The new status values are: PENDING, SUCCESS, PARTIAL, FAILURE and DISCARDED.

10. Added 'chainId' array to the 'wallet_getCapabilities' request

It seems like a wallet that supports a very long list of chains would be forced to return an unusually large JSON object as a response. However, as most dapps know which chains they may run on, it makes sense for them to limit the scope of the request.

11. Added SemVer 'version' parameter to capabilities.

It is not likely that all 'capabilities' will reach their final version from day one.
As there was no built-in mechanism for versioning, and having no centralized "capabilities authority", it would be pretty likely to see capabilities like 'paymasterServiceV2' and 'atomicBatch_3' proliferate, creating a lot of confusion.