From 2463000ede8ab3d5cdba10943e27ba25dfa77ecb Mon Sep 17 00:00:00 2001 From: Moody Salem Date: Mon, 14 Nov 2022 18:35:29 -0500 Subject: [PATCH] EIP-5072 edits (#5931) * remove optional * some language cleanup --- EIPS/eip-5792.md | 102 ++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/EIPS/eip-5792.md b/EIPS/eip-5792.md index fd6617e9b187a9..10623574909157 100644 --- a/EIPS/eip-5792.md +++ b/EIPS/eip-5792.md @@ -1,7 +1,7 @@ --- eip: 5792 title: Wallet Function Call API -description: Adds JSON-RPC methods for sending multiple function calls from a wallet, and checking their status +description: Adds JSON-RPC methods for sending multiple function calls from the user's wallet, and checking their status author: Moody Salem (@moodysalem) discussions-to: https://ethereum-magicians.org/t/eip-5792-wallet-abstract-transaction-send-api/11374 status: Draft @@ -13,41 +13,42 @@ created: 2022-10-17 ## Abstract Defines new JSON-RPC methods for dapps to send batches of function calls from a user's wallet, as well as check -on the status of these calls. These new methods are more abstract than the existing transaction sending APIs -to allow for differences between wallets in how function calls are sent on-chain, e.g. smart contract wallets -utilizing [EIP-4337](./eip-4337.md) or EOA wallets that support bundled transactions via [EIP-3074](./eip-3074.md). -Dapps may use this more abstract interface to support different kinds of wallets, as well as provide a better UX for -sending bundles of function calls (e.g. [EIP-20](./eip-20.md)`#approve` followed by a contract call). +on the status of those calls. The new methods are more abstract in regard to the underlying transactions than the +existing transaction sending APIs to allow for differences between wallet implementations, e.g. +smart contract wallets utilizing [EIP-4337](./eip-4337.md) or EOA wallets that support bundled transactions +via [EIP-3074](./eip-3074.md). Dapps may use this more abstract interface to support different kinds of wallets without +additional effort, as well as provide a better UX for sending bundles of function calls ( +e.g. [EIP-20](./eip-20.md) `#approve` followed by a contract call). ## Motivation -The current methods to send transactions from the user wallet and check their status are `eth_sendTransaction` +The current methods used to send transactions from the user wallet and check their status are `eth_sendTransaction` and `eth_getTransactionReceipt`. -One problem with these methods is that they are keyed on the hash of the on-chain transaction, -i.e. `eth_sendTransaction` returns an transaction hash computed from the transaction parameters, -and `eth_getTransactionReceipt` takes as one argument the transaction hash. When the transaction hash changes, for -example when a user speeds up the transaction in their wallet, the transaction hash that the dapp is aware of becomes -irrelevant. There is no communication delivered to the dapp of the change in transaction hash, and no way to connect the -old transaction hash to the new one, except by the user account and transaction nonce. It is not trivial for the dapp -to find all signed transactions for a given nonce and account, especially for smart contract accounts which usually -store the nonce in a contract storage slot. This happens more frequently with smart contract wallets, which usually use -a third party relayer and automatically re-broadcast transactions with higher gas prices. - -Another problem with these methods is that they do not support sending multiple function calls related to a single -action. For example, when swapping on Uniswap, the user must often call [EIP-20](./eip-20.md)`#approve` -before calling the Uniswap router contract to swap. The dapp has to manage a complex multi-step asynchronous workflow to -guide the user through sending a single swap. The ideal UX would be to bundle the approve call with the swap call, and -abstract the underlying approve function call from the user. - -The interface also does not work well for account abstracted wallets (e.g. [EIP-4337](./eip-4337.md) -or [EIP-3074](./eip-3074.md)), which often involve a third party relayer to sign the transaction that triggers the -function calls from the user's wallet. In these cases the actual transaction hash may not be known at the time of user -signing, but must still be returned by `eth_sendTransaction`. The transaction hash returned by `eth_sendTransaction` in -these cases is unlikely to be relevant to the transaction hash of the included transaction. The existing interface also -provides no way to delay the resolution of the transaction hash, since it is used as the key of the transaction tracked -by the dapp. Dapps often link to the block explorer for the returned transaction hash, but in these cases the -transaction hash is wrong and the link will not work. +These methods are keyed on the hash of the on-chain transaction, i.e. `eth_sendTransaction` returns an transaction hash +computed from the transaction parameters, and `eth_getTransactionReceipt` takes as one argument the transaction hash. +When the transaction hash changes, for example when a user speeds up the transaction in their wallet, the transaction +hash that the dapp is aware of becomes irrelevant. There is no communication delivered to the dapp of the change in +transaction hash, and no way to connect the old transaction hash to the new one, except by the user account and +transaction nonce. It is not trivial for the dapp to find all signed transactions for a given nonce and account, +especially for smart contract accounts which usually store the nonce in a contract storage slot. This happens more +frequently with smart contract wallets, which usually use a third party relaying service and automatically re-broadcast +transactions with higher gas prices. + +These methods also do not support sending multiple function calls related to a single action. For example, when swapping +on Uniswap, the user must often call [EIP-20](./eip-20.md) `#approve` before calling the Uniswap router contract to +swap. The dapp has to manage a complex multi-step asynchronous workflow to guide the user through sending a single swap. +The ideal UX would be to bundle the approve call with the swap call, and abstract the underlying approve function call +from the user. + +The current interface also does not work well for account abstracted wallets (e.g. [EIP-4337](./eip-4337.md) +or [EIP-3074](./eip-3074.md)), which often involve a relaying service to sign and broadcast the transaction that +triggers the function calls from the user's wallet. In these cases the actual transaction hash may not be known at the +time of user signing, but must still be returned by `eth_sendTransaction`. The transaction hash returned +by `eth_sendTransaction` in these cases is unlikely to be relevant to the transaction hash of the included transaction. +The existing interface also provides no way to delay the resolution of the transaction hash, since it is used as the key +of the transaction tracked by the dapp. Dapps often link to the block explorer for the returned transaction hash, but in +these cases the transaction hash is wrong and the link will not work. Dapps need a better interface for sending batches of function calls from the user's wallet so they can interact with wallets without considering the differences between wallet implementations. These methods are backwards compatible with @@ -64,16 +65,16 @@ to `eth_sendTransaction` and `eth_getTransactionReceipt` when they are not avail Requests that the wallet deliver a group of function calls on-chain from the user's wallet. -- The wallet MUST send these calls in the order specified in the request. -- The wallet MAY send all the function calls as part of a single transaction, or multiple transactions. -- Dapps MUST NOT rely on the calls being sent in an atomic transaction, i.e. other untrusted calls may be - included between each of the requested function calls. -- The wallet MUST attempt to deliver all calls if it returns a successful response to this method, and the wallet - MUST NOT deliver any calls if it returns an error response. -- The wallet MAY reject the request if the request chain ID does not match the currently selected chain ID. -- The wallet MUST send the calls on the request chain ID. -- The wallet MAY reject the request if the `from` address does not match the enabled account. -- The wallet MAY reject the request if one or more calls in the bundle will fail. +The wallet: +- MUST send these calls in the order specified in the request. +- MUST send the calls on the request chain ID. +- MUST stop executing the calls if any call fails +- 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 the function calls as part of one transaction or multiple transactions, depending on wallet capability. +- MAY reject the request if the request chain ID does not match the currently selected chain ID. +- 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 bundle is expected to fail, when simulated sequentially #### `wallet_sendFunctionCallBundle` OpenRPC Specification @@ -127,10 +128,6 @@ Requests that the wallet deliver a group of function calls on-chain from the use title: data description: The data to send with the function call $ref: '#/components/schemas/bytes' - optional: - title: optional - description: Whether the call must succeed for subsequent calls to be made - type: boolean result: name: Bundle identifier schema: @@ -150,8 +147,7 @@ Requests that the wallet deliver a group of function calls on-chain from the use "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", "gas": "0x76c0", "value": "0x9184e72a", - "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", - "optional": true + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" }, { "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", @@ -270,19 +266,25 @@ As with the return value of `wallet_sendFunctionCallBundle`, the bundle identifi It may be the hash of the call bundle: ```json -["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"] +[ + "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" +] ``` It may contain a numeric identifier as a hex string: ```json -["0x01"] +[ + "0x01" +] ``` It may be a base64 encoded string: ```json -["aGVsbG8gd29ybGQ="] +[ + "aGVsbG8gd29ybGQ=" +] ``` ##### `wallet_getBundleStatus` Example Return Value