EIP-5792: Wallet Call API
Adds JSON-RPC methods for sending multiple calls from the user's wallet, and checking their status
What does EIP-5792 do?
Adds JSON-RPC methods for sending multiple calls from the user's wallet, and checking their status.
Why is it important?
Enables batch transactions for wallets, so that transactions can be bundled together and sponsored by apps if they wish. This ties to EIP-3074.
Abstract
Defines new JSON-RPC methods which enable apps to ask a wallet to process a batch of onchain write calls and to check on the status of those calls. Applications can specify that these onchain calls be executed taking advantage of specific capabilities previously expressed by the wallet; an additional, a novel wallet RPC is defined to enable apps to query the wallet for those capabilities.
Motivation
The current methods used to send transactions from the user wallet and check their status are eth_sendTransaction
and eth_getTransactionReceipt
.
The current methods used to send transactions from the user wallet and check their status do not meet modern developer demands and cannot accommodate new transaction formats. Even the name–- eth_sendTransaction
-– is an artifact of a time when nodes served as wallets.
Today, developers want to send multiple calls batched together in a single RPC call, which many smart accounts can, in turn, execute atomically in a single transaction. Developers also want to make use of features afforded by new transaction formats, like paymasters in ERC-4337 transactions. eth_sendTransaction
offers no way to do these things.
In updating to a new set of wallet_
RPCs, our main goals are to enforce a clean separation of wallet and app concerns, enable developers to make use of things like paymasters and batch transactions, and to create a clear way for more safely discoverable features to be added over time with minimal coordination.
Specification
Four new JSON-RPC methods are added: three are for handling batches of onchain calls, and one is for querying support for wallet capabilities, such as to make better use of the three batching methods.
Apps may begin using these first three methods immediately, falling back to eth_sendTransaction
and eth_getTransactionReceipt
when they are not available.
We also define one capability expression for use with the fourth method, which further enables a wallet to promise atomicity of the execution of calls passed and managed by the first three methods.
wallet_sendCalls
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, identified by EIP-155 integers expressed in hexadecimal notation. The items in the calls
field are only those that are shared by all transaction types. Any other fields that a wallet may need to submit a transaction should be handled by the wallet.
The capabilities field is how an app can communicate with a wallet about capabilities a wallet supports. For example, this is where an app can specify a paymaster service URL from which an ERC-4337 wallet can request a paymasterAndData
input for a user operation.
The wallet:
- MUST send the calls in the order specified in the request
- MUST send the calls on the same chain identified by the call's
chainId
property - MUST NOT await for any calls to be finalized to complete the batch
- MUST NOT send any calls from the request if the user rejects the request
- MAY revert all calls if any call fails
- MAY send all calls as part of one or more transactions, depending on wallet capability
- SHOULD stop executing the calls if any call fails
- MAY reject the request if the from address does not match the enabled account
- MAY reject the request if one or more calls in the batch is expected to fail, when simulated sequentially
wallet_sendCalls
RPC Specification
wallet_sendCalls
Example Parameters
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.
wallet_getCallsStatus
Returns the status of a call batch that was sent via wallet_sendCalls
. The identifier of the transaction is the value returned from the wallet_sendCalls
RPC. Note that this method only returns a subset of the fields that eth_getTransactionReceipt
returns, excluding any fields that may differ across wallet implementations.
- If a wallet does not execute multiple calls atomically (i.e. in multiple transactions), the receipts in the
receipts
field MUST be in order of the calls sent. - If a wallet executes multiple calls atomically (i.e. in a single transaction),
wallet_getCallsStatus
MUST return a single receipt, corresponding to the transaction in which the calls were included. - The
logs
in the receipt objects MUST only include logs relevant to the calls submitted usingwallet_sendCalls
. For example, in the case of a transaction submitted onchain by an ERC-4337 bundler, the logs must only include those relevant to the user operation constructed using the calls submitted viawallet_sendCalls
. I.e. the logs should not include those from other unrelated user operations submitted in the same bundle.
wallet_getCallsStatus
RPC Specification
wallet_getCallsStatus
Example Parameters
As with the return value of wallet_sendCalls
, the batch identifier may be any string.
wallet_getCallsStatus
Example Return Value
wallet_showCallsStatus
Requests that a wallet shows information about a given call bundle that was sent with wallet_sendCalls
. Note that this method does not return anything.
wallet_showCallsStatus
RPC Specification
wallet_showCallsStatus
Example Parameters
This method accepts a call bundle identifier returned by a wallet_sendCalls
call.
wallet_getCapabilities
This RPC allows an application to request capabilities from a wallet (e.g. batch transactions, paymaster communication), without distinct discovery and permission requests. For more on the difference between requesting capabilities and discoverying features, see the "Privacy Considerations" section.
This method SHOULD return an error if the user has not already authorized a connection between the application and the requested address.
We expect the community to align on the definition of additional capabilities in separate ERCs over time.
Note that in addition to, or instead of, querying the wallet directly for capabilities, the same capability objects MAY be exposed out-of-band, such as in a sessionProperty.capabilities
object persisted in a CAIP-25-conformant wallet provider interface, or in a well-known location (such as a URL derived from an EIP-6963 rdns
identifier).
Provider abstractions MAY also cache capabilities from previous requests or otherwise inject them from out-of-band to facilitate better user experience.
If any of these supplemental expressions of capabilities are contradicted by capabilities expressed in live wallet RPC responses, these latter values SHOULD be taken as the canonical and current expression of capabilities.
wallet_getCapabilities
RPC Specification
Capabilities are returned in key/value pairs, with the key naming a capability and a value conforming to a shape defined for that name, in an object keyed to the relevant EIP-155 chainId
expressed in hexadecimal notation.
Capabilities are nested in per-chain objects because wallets may support different capabilities across multiple chains authorized in a given session.
wallet_getCapabilities
Example Parameters
wallet_getCapabilities
Example Return Value
The capabilities below are for illustrative purposes.
atomicBatch
Capability
Like the illustrative examples given above and other capabilities to be defined in future EIPs, the capability to execute calls delivered via the above-defined methods in a single transaction can be attested by the wallet in boolean form.
This capability is expressed separately on each chain and should be interpreted as a guarantee only for batches of transactions on that chain; batches including calls to multiple chains is out of scope of this capability and this specification.
If a wallet has affirmatively expressed this atomicBatch
capability to a calling application, it MUST submit calls submitted with wallet_sendCalls
as part of a single transaction.
atomicBatch
Capability Specification
The only valid JSON-RPC values for this capability's only member, supported
, are true
or false
; if a returned value for supported
is typed as a string or number, it SHOULD be considered malformed.
For each chain on which a wallet can submit multiple calls atomically, the wallet SHOULD include an atomicBatch
capability with a supported
field equal to true
.
wallet_getCapabilities
Example Return Value including atomicBatch
Rationale
On Naming
We considered modifying eth_sendTransaction
to add support for these new capabilities, but the method is ultimately an artifact of when nodes were used to sign transactions. We decided it is better to move forward with wallet_
-namespaced methods that better describe what they are used for.
We also debated whether the methods should be called wallet_sendTransaction
, wallet_sendCalls
, or something else. We ultimately landed on wallet_sendCalls
because in the case of EOA wallets the wallet_send*
method might send more than one transaction. Similarly, we decided against wallet_sendTransactions
because in the case of other wallet implementations (e.g. ERC-4337) multiple calls could result in a single transaction.
Call Execution Atomicity
The wallet_sendCalls
method accepts an array of calls
. However, this proposal does not require that these calls be executed as part of a single transaction. It enables EOA wallets to accept multiple calls as well over the same interface. That said, we expect that in some cases app developers might want to submit batched calls if and only if they will be executed atomically. This would reduce the number of error cases an app developer would need to handle, while still contributing to the unification over time of interfaces across wallets types.
We initially proposed that multiple calls must be executed atomically, but after some debate we ultimately decided this was too opinionated. Instead, we are including a specification for an atomicBatch
capability. This allows for EOA wallets to accept multiple calls and still gives developers the option to only submit batched calls if they are executed atomically.
Call Gas Limit
Our initial proposal included an optional gas
field for each call in the calls
field accepted by the walletSendCalls
method. However, we realized this could be misleading because in the case of ERC-4337 wallets you cannot specify a gas limit per call, only a single gas limit for all calls in the user operation. We then proposed a single gas
value that would apply to all of the calls. This works for ERC-4337 wallets, but not for EOA wallets. When we decided that EOA wallets should be able to handle multiple calls, the common gas
field became untenable across use cases and we removed it altogether.
Backwards Compatibility
Wallets that do not support the methods defined here SHOULD return error responses when these new JSON-RPC methods are called. Apps MAY attempt to send the same batch of calls serially via eth_sendTransaction
when a call to these methods fails for lack of wallet support, or they MAY indicate to the user that their wallet is not supported and the request was not processed.
Security Considerations
App developers MUST treat each call in a batch as if the call were an independent transaction. In other words, there may be additional untrusted transactions between any of the calls in a batch. The calls in the batch MAY also be included in separate, non-contiguous blocks. There is no constraint over how long it will take all the calls in a batch to be included. Apps MUST encode deadlines and timeout behaviors in the smart contract calls, just as they do today for transactions, including ones otherwise bundled. Unless a wallet has indicated affirmatively to the application that it can submit batched calls atomically via capability declarations, app developers MUST NOT assume that all calls will be sent in a single transaction.
Privacy Considerations
Progressive authorization and progressive consent paradigms are important to modern user experience, as well as to preserving the anonymity of user agents. To protect these patterns from the cross-incentives of feature-discovery that enables better user experiences, capability semantics are used and the difference between lack of feature support and lack of feature permission explicitly occluded in the design of the wallet_
RPC for querying capabilities.
Furthermore, wallets are recommended to avoid exposing capabilities to untrusted callers or to more callers than necessary, as this may allow their "user-agent" (i.e. client software) to be "fingerprinted" or probabilistically identified, which combined with other deanonymization vectors inherent to the web platform could contribute to the deanonymization of the individual user or to the deanonymization of all users of a given client in aggregate. Similarly, applications over-querying capabilities or incentivizing capability oversharing (including third-party capability oversharing) is an anti-pattern to be avoided in the implementation of capability exchanges serving to discover features.
Copyright
Copyright and related rights waived via CC0.