# Proposal for New Wallet RPCs ## Introduction Two of the most sought after features that come with our new Smart Wallet are the ability to use paymasters and the ability to submit batch transactions. While our Smart Wallet can both use paymasters and submit batch transactions, there is currently no way for applications to communicate with our wallet about either of these things. We considered modifying `eth_sendTransaction` to add support for these newer features, but it's ultimately an artifact of when nodes were used to sign transactions. Instead of forcing these needs into existing methods, we should create a new set of RPCs in the `wallet_` namespace that give developers access to these new features. This document proposes a spec for these new RPCs. At a high level, the proposed RPCs are: * `wallet_getCapabilities` * RPC for open ended communication between an app and wallet about features that a given wallet supports (eg paymaster communication) * `wallet_sendTransaction` * Requests that a connected wallet submits a specified transaction, adhering to capabilities passed in if applicable. Returns a transaction identifier defined by the wallet. * `wallet_getTransactionStatus` * Gets the status of a transaction given an id * `wallet_showTransactionStatus` * Requests that a connected wallet shows the status of a transaction given an id ## Specifications ### `wallet_getCapabilities` RPC for an application to receive information about the features that a connected wallet supports. At a minimum, each entry should include a `supported` field that indicates whether or not a wallet supports a given capability. We expect the community to align on any additional fields that should be included for a given capability. #### Parameters None #### Return value ```json { "description": "A wallet's capabilities. Each entry's key should represent an independently defined capability, and its value can be any shape. The only requirement is that there is a supported field that indicates whether or not a given capability is supported by the wallet.", "type": "object", "patternProperties": { "^.*$": { "type": "object", "properties": { "supported": { "description": "Indicates whether or not a given capability is supported.", "type": "boolean" } } } } } ``` ### `wallet_sendTransaction` Requests that a wallet submits a transaction. Sender and chain id are top level because all calls should be sent from the same sender on the same chain. 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 `calls` field is an array, where length can be greater than one if wallets choose to accept more than one call in a single `wallet_getTransaction` call. This could mean, for example, an EOA that accepts multiple calls in one `wallet_getTransaction` call and executes each call in sequence. It could also mean an ERC-4337 wallet that accepts multiple calls and executes them as part of a single user operation. Applications can find out if a wallet accepts multiple calls in a single `wallet_sendTransaction` call by calling `wallet_getCapabilities`. If a wallet does support multiple calls, the `wallet_getCapabilities` call should include a `batchTransactions` entry, with a `supported` field equal to `true`. #### Parameters ```json { "type": "object", "properties": { "chainId": { "description": "The chain id to submit the transaction on", "type": "integer" }, "sender": { "description": "Address the transaction will be sent from", "$ref": "#/definitions/address" }, "calls": { "description": "Calls to be executed. This could be done as one batch call if the wallet supports it, or in sequence", "type": "array", "items": { "type": "object", "properties": { "target": { "description": "Target address of the call", "$ref": "#/definitions/address" }, "value": { "description": "Value in wei sent with the call", "$ref": "#/definitions/uint256" }, "data": { "description": "A contract hashed method call with encoded args", "$ref": "#/definitions/bytes" }, "gas": { "description": "Gas limit for the call", "$ref": "#/definitions/uint256" } } } }, "capabilities": { "description": "Corresponds to a wallet's capabilities, returned from wallet_getCapabilities. The definition of each capability will define how to specify its entry in this field.", "type": "object" } }, "definitions": { "address": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "uint256": { "type": "string", "pattern": "^0x[a-fA-F0-9]{1,64}$" }, "bytes": { "type": "string", "pattern": "^0x[a-fA-F0-9]*$" } } } ``` #### Return value ```json { "description": "An identifier for the submitted transaction. Wallets can choose any string to identify transactions. The only requirement is that for a given session, users should be able to call wallet_getTransactionStatus & wallet_showTransactionStatus with this value and get a transaction status / have the wallet show the status of a transaction, respectively.", "type": "string" } ``` ### `wallet_getTransactionStatus` Inspired by EIP-5792’s [`wallet_getBundleStatus`](https://eips.ethereum.org/EIPS/eip-5792#wallet_getbundlestatus). For each submitted call to `wallet_sendTransaction`, returns a status of `CONFIRMED` or `PENDING` and a subset of fields that `eth_getTransactionReceipt` returns, excluding any fields that may differ across wallet implementations. #### Parameters ```json { "description": "A transaction identifier, returned by wallet_sendTransaction", "type": "string" } ``` #### Return value ```json { "type": "object", "calls": { "description": "The statuses of calls corresponding to calls submitted to a wallet via wallet_sendTransaction.", "type": "array", "items": { "type": "object", "properties": { "status": { "type": "string", "enum": [ "CONFIRMED", "PENDING" ] }, "receipt": { "description": "Transaction receipt for a given call, if applicable. These could be different across multiple calls, or the same if they were submitted in one transaction (eg as part of one ERC-4337 user operation).", "type": "object", "properties": { "logs": { "description": "Transaction logs", "type": "array", "items": { "type": "object", "properties": { "address": { "$ref": "#/definitions/address" }, "topics": { "type": "array", "items": { "$ref": "#/definitions/bytes32" } }, "data": { "$ref": "#/definitions/bytes" } } } }, "success": { "type": "boolean" }, "blockHash": { "$ref": "#/definitions/bytes32" }, "blockNumber": { "$ref": "#/definitions/uint256" }, "blockTimestamp": { "$ref": "#/definitions/uint256" }, "gasUsed": { "$ref": "#/definitions/uint256" }, "transactionHash": { "$ref": "#/definitions/bytes32" } } } } } }, "definitions": { "address": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" }, "uint256": { "type": "string", "pattern": "^0x[a-fA-F0-9]{1,64}$" }, "bytes": { "type": "string", "pattern": "^0x[a-fA-F0-9]*$" }, "bytes32": { "type": "string", "pattern": "^0x[a-fA-F0-9]{64}$" } } } ``` ### `wallet_showTransactionStatus` Inspired by EIP-5792’s [`wallet_showBundleStatus`](https://eips.ethereum.org/EIPS/eip-5792#wallet_showbundlestatus). Note that this method does not return anything. It instead requests that a wallet shows information about a specified transaction that was sent with `wallet_sendTransaction`. #### Parameters ```json { "description": "A transaction identifier, returned by wallet_sendTransaction", "type": "string" } ``` #### Return value None ## Paymaster: Capabilities Example in Detail In addition to the new wallet RPCs specified above, we propose a spec to support a paymaster wallet capability at launch. Beyond this proposal, we expect the community to align around new capabilities, their naming, and what support for them means in practice. Regarding the proposed paymaster capability: * Wallets that support paymasters should indicate this as part of their response to a `wallet_getCapabilities` request * Wallets that support paymasters should use the paymaster specified in a `wallet_sendTransaction` call Specifically, a wallet that supports paymasters should return the following in response to a `wallet_getCapabilities` request: ```json { ... "paymaster": { "supported": true } ... } ``` Additionally, `wallet_sendTransaction` accepts a `paymaster` entry in the `capabilities` field. The paymaster capability has a `url` field, indicating the URL of the paymaster. Example: ```javascript wallet_sendTransaction({ chainId: 8453, sender: "0x...", calls: [ { target: "0x...", value: "0x...", data: "0x..." } ], capabilities: { paymaster: { url: "https://paymaster.base.org" } } }) ``` When a wallet supports paymasters and a `wallet_sendTransaction` request specifies a paymaster in the `capabilities` field, the wallet should use the specified paymaster. There’s a problem though: just because a wallet knows the URL of the paymaster an application wants it to use doesn’t mean it knows how to communicate with the paymaster. To fix this, paymasters should add support for two standardized RPCs: * `pm_getStubPaymasterData` * Standard RPC to get dummy paymaster signatures for gas estimation * `pm_getPaymasterData` * Standard RPC to get paymaster signatures for a user operation Both of these proposed paymaster service RPC methods accept as parameters: * `Object` Unsigned user operation * `string` Entrypoint address * `string` Chain id in hex Both of these proposed paymaster service RPC methods return the paymaster and data to be used in a user operation’s `paymasterAndData` field. `pm_getStubPaymasterData` returns a dummy value that should only be used for gas estimation. `pm_getPaymasterData` returns a real signature that should be used as part of an eth_sendUserOperation call. Below is a diagram of what the full flow would look like for sending a transaction for an ERC-4337 wallet that supports paymasters. ![example](https://hackmd.io/_uploads/HylAK30Dpp.png)