Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update EIP-5792: Propose changes to EIP-5792 #8826

Merged
merged 62 commits into from
Feb 27, 2025
Merged
Changes from 34 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
40d79c7
Propose changes to EIP-5792
forshtat Aug 25, 2024
a97f3a2
Update EIPS/eip-5792.md
forshtat Aug 26, 2024
d14ce17
Rename status response field from 'capabilitiesData' to 'capabilities…
forshtat Sep 4, 2024
0ecea7b
Change batch identifier size from 32 bytes to 64 bytes
forshtat Sep 4, 2024
b364b92
Rename 'batchId' to 'callsId'
forshtat Nov 21, 2024
84c6d4d
update 5792 with more specifics re capabilities
lukasrosario Dec 5, 2024
2c3d75e
update atomicBatch
lukasrosario Dec 5, 2024
b769acc
formatting
lukasrosario Dec 5, 2024
c837526
more formatting
lukasrosario Dec 5, 2024
b8e75d5
Merge pull request #11 from lukasrosario/lukas/update-capabilities-sp…
forshtat Dec 6, 2024
b337a12
Add
forshtat Dec 6, 2024
e10da9a
update status codes
lukasrosario Jan 8, 2025
0a705ca
lint
lukasrosario Jan 8, 2025
41b1024
push
lukasrosario Jan 8, 2025
4253f62
Merge branch 'eip-5792-proposal' into lukas/add-statuses
lukasrosario Jan 8, 2025
cfe2529
add note
lukasrosario Jan 8, 2025
c6f2700
lint
lukasrosario Jan 8, 2025
ad36c64
address comments
lukasrosario Jan 10, 2025
746cc8c
add capabilities to response
lukasrosario Jan 11, 2025
15e27af
Merge pull request #12 from lukasrosario/lukas/add-statuses
forshtat Jan 13, 2025
00b6242
switch error status codes
lukasrosario Jan 14, 2025
2ef7d48
Merge pull request #13 from lukasrosario/lukas/switch-status-codes
forshtat Jan 15, 2025
baeeb02
Remove 'atomicBatch' capability; clean up ambiguity; add 'wallet_show…
forshtat Jan 16, 2025
20ccae2
Rephrase mixing `optional` and MUST in one sentence
forshtat Jan 16, 2025
f88f6ed
Remove rationale for `from` and `chainId` being top-level
forshtat Jan 16, 2025
b89b616
Make 'status' field a 'number'
forshtat Jan 16, 2025
6bfea5b
Rephrase the optional capability example
forshtat Jan 16, 2025
b9c213a
Rephrase stopping after error rule
forshtat Jan 16, 2025
2995ac0
Rephrase call batch status within session rule
forshtat Jan 16, 2025
7516f52
Grammar
forshtat Jan 16, 2025
80fbeb4
status type fix
lukasrosario Jan 16, 2025
5ff15e7
Merge pull request #14 from lukasrosario/lukas/status-example-fix
forshtat Jan 16, 2025
54a6243
Elaborate "atomic unit in a single transaction"
forshtat Jan 16, 2025
0de3f96
Move "unless" part of the wallet rules to the top of the list
forshtat Jan 16, 2025
8532ab0
make 'from' optional
lukasrosario Jan 17, 2025
e457851
move status codes, add clarification on 'from' param
lukasrosario Jan 17, 2025
04d4525
Update eip-5792.md
forshtat Jan 17, 2025
0b506c0
Merge pull request #15 from lukasrosario/lukas/optional-from
forshtat Jan 17, 2025
9d6d4e9
Explicitly require '0x' and ban leading zeroes
forshtat Jan 21, 2025
534c81b
Define the Capability type
forshtat Jan 21, 2025
77f32cc
Replace "session" with a 24 hour window as a rule is "SHOULD" anyways
forshtat Jan 21, 2025
a3d61d3
Reword the 'wallet_getCallsStatus' receipt(s) rules
forshtat Jan 22, 2025
7701a64
Introduce a 600 status category for partial on-chain revert
forshtat Jan 22, 2025
1be7d7d
Explicitly return 4100 Unauthorized error in 'wallet_getCapabilities'
forshtat Jan 22, 2025
a0ff4d7
Update eip-5792.md: Add myself as author
SamWilsn Jan 22, 2025
30c907f
Merge pull request #18 from SamWilsn/patch-1
forshtat Jan 22, 2025
08b645c
remove security consideration section
lukasrosario Jan 22, 2025
9a88ef6
add a security consideration
lukasrosario Jan 22, 2025
5f5d026
better
lukasrosario Jan 22, 2025
379a2f3
Merge pull request #19 from lukasrosario/lukas/atomicity-feedback
forshtat Jan 22, 2025
97175a3
add optional id
lukasrosario Jan 27, 2025
3f37aaa
feedback
lukasrosario Jan 29, 2025
ffe443c
change response capability interface
lukasrosario Jan 29, 2025
10f6d85
Merge pull request #20 from lukasrosario/lukas/optional-id
forshtat Jan 29, 2025
ca8dcc2
feedback
lukasrosario Feb 3, 2025
2dcee4d
Merge pull request #21 from lukasrosario/feedback
forshtat Feb 3, 2025
03b1d03
add: Borislav Itskov as co-author
borislav-itskov Feb 4, 2025
ddf53b1
Add 'version' to the 'wallet_getCallsStatus' return value object
forshtat Feb 12, 2025
e8e1400
Update eip-5792.md
forshtat Feb 12, 2025
8fa2c54
Add special "0x0" chainID for universally supported capabilities
forshtat Feb 20, 2025
29d4589
Merge pull request #22 from borislav-itskov/eip-5792-proposal
forshtat Feb 21, 2025
06a9997
Replace 'change' with 'select'
forshtat Feb 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 81 additions & 74 deletions EIPS/eip-5792.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
eip: 5792
title: Wallet Call API
description: Adds JSON-RPC methods for sending multiple calls from the user's wallet, and checking their status
author: Moody Salem (@moodysalem), Lukas Rosario (@lukasrosario), Wilson Cusack (@wilsoncusack), Dror Tirosh (@drortirosh), Jake Moxey (@jxom), Derek Rein (@arein)
author: Moody Salem (@moodysalem), Lukas Rosario (@lukasrosario), Wilson Cusack (@wilsoncusack), Dror Tirosh (@drortirosh), Jake Moxey (@jxom), Derek Rein (@arein), Alex Forshtat (@forshtat)
discussions-to: https://ethereum-magicians.org/t/eip-5792-wallet-abstract-transaction-send-api/11374
status: Last Call
last-call-deadline: 2024-09-05
Expand All @@ -20,7 +20,7 @@ Applications can specify that these onchain calls be executed taking advantage o

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.
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](./eip-4337.md) transactions. `eth_sendTransaction` offers no way to do these things.

Expand All @@ -31,42 +31,55 @@ In updating to a new set of `wallet_` RPCs, our main goals are to enforce a clea
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](./eip-155.md) 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.
Requests that a wallet submits a batch of calls. `from` and `chainId` are identified by [EIP-155](./eip-155.md) integers expressed in hexadecimal notation.
The items in the `calls` field are simple `{to, data, value}` tuples.

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](./eip-4337.md) wallet can request a `paymasterAndData` input for a user operation.

Each capability defined in the "capabilities" member can define global or call specific fields.
These fields are set inside this capability's entry in the `capabilities` object.
Each entity in the `calls` field may contain an optional `capabilities` object.
This object allows the applications to attach a capability-specific metadata to individual calls.

Unless these requirements are explicitly overriden by a certain `capability`, the wallet must adhere to the following rules.
Note that such a `capability` is not in the scope of this EIP and should be defined in its own ERC.

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 send the calls on the same chain identified by the request's `chainId` property
* MUST NOT await for any calls to be finalized to complete the batch
* MUST submit multiple calls as an atomic unit in a single transaction
* 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
* MUST not execute any further calls after a failed call
* 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
* MUST reject the request if it contains a `capability` (either top-level or call-level) that is not supported by the wallet and the `capability` is not explicitly marked as optional.
* Applications may mark a capability as optional by setting `optional` to `true`. See the RPC Specification section below for details.

#### `wallet_sendCalls` RPC Specification

```typescript
type SendCallsParams = {
version: string;
from: `0x${string}`;
chainId: `0x${string}` | undefined; // Hex chain id
calls: {
to?: `0x${string}` | undefined;
data?: `0x${string}` | undefined;
value?: `0x${string}` | undefined; // Hex value
chainId?: `0x${string}` | undefined; // Hex chain id
capabilities?: Record<string, any> | undefined;
}[];
capabilities?: Record<string, any> | undefined;
Copy link
Contributor

@SamWilsn SamWilsn Jan 15, 2025

Choose a reason for hiding this comment

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

I'd recommend defining a Capability type. Maybe something like:

interface Capability {
  [key: string]: unknown;
  optional?: boolean;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

};

type SendCallsResult = string;
type SendCallsResult = {
id: string;
capabilities?: Record<string, any> | undefined;
};
```

##### `wallet_sendCalls` Example Parameters
Expand All @@ -76,43 +89,54 @@ type SendCallsResult = string;
{
"version": "1.0",
"from": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"chainId": "0x01",
"calls": [
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"value": "0x9184e72a",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675",
"chainId": "0x01",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
},
{
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"value": "0x182183",
"data": "0xfbadbaf01",
"chainId": "0x01",
"data": "0xfbadbaf01"
}
],
"capabilities": {
// Illustrative
"paymasterService": {
"url": "https://..."
"url": "https://...",
"optional": true
}
}
}
]
```

Note that since the `paymasterService` `capability` is marked as optional, wallets that do not support it will still process and handle the request as if the capability had not been present. If this `optional` field were set to `false` or absent from the request, wallets that do not support the `capability` MUST reject the request.

##### `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 identifier MUST be unique 64 bytes represented as a hex encoded string.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is ambiguous. Unique how? Unique throughout Ethereum? Unique to the address making the calls? Unique to the session?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think a 64 bit identifier can be assumed globally unique for the purpose of this EIP, but we can add "for the current session".
But, as you've mentioned, we did not yet define what a "session" actually is for the wallet_sendCalls.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could also make it explicitly more limited, something like "The identifier MUST be unique for a given RPC provider within a 24 hour window. It is 64 bytes long and is represented as a hex encoded string."

What do you think? The 24 hour window comes from this commit:

77f32cc

Copy link
Contributor

@jxom jxom Jan 22, 2025

Choose a reason for hiding this comment

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

What is the rationale behind a strict 64-byte identifier? 🤔 A lot of folks could be using 32-byte hashes for these identifiers? Some Wallets could also just return a transaction hash if they support 7702.

While within the same session as the corresponding `wallet_sendCalls`, wallets SHOULD return a call-batch status when `wallet_getCallsStatus` is called with this value.

The `capabilities` object allows the wallets to attach a capability-specific metadata to the response.

```json
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
{
"id": "0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
}
```

### `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.
Returns the status of a call batch that was sent via `wallet_sendCalls`.
The identifier of the batch is the value returned from the `wallet_sendCalls` RPC.
Note that the `receipts` objects of this method's response is a strict subset of the object returned by `eth_getTransactionReceipt`.

* 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.
The `capabilities` object allows the wallets to attach a capability-specific metadata to the response.

* The receipts in the `receipts` field MUST be in the order that they are included onchain.
* The `receipts` field MUST contain receipts for all calls in a batch that were included onchain, including reverted ones.
* 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

These two lines confuse me. Does a receipt include multiple calls? If so, I'd clarify the wording in the document.

I'd also argue that there could be a case for multiple transactions implementing a single atomic batch. A contrived example might be a multisig wallet, where each signature is recorded in a transaction, then applied atomically once the quorum is reached.

Copy link
Contributor

Choose a reason for hiding this comment

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

IIUC:

  • if the sendCalls performs an atomic transaction (as is the default for this ERC), then there is a single receipt for the transaction itself - not for each inner call.
  • if there are separate transactions for the calls (which is not fully specified in this ERC) - then there is a receipt for each call.

multisig wallet, where each signature is recorded in a transaction, then applied atomically once the quorum is reached.
If each multisig owner separately submits a transaction with its own signature, then each of them is a separate transaction, originated by separate wallets. The last owner signature is batched transaction with the multisig execute that uses all these partial signatures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rephrased a little:
a3d61d3

* The `logs` in the receipt objects MUST only include logs relevant to the calls submitted using `wallet_sendCalls`. For example, in the case of a transaction submitted onchain by an [ERC-4337](./eip-4337.md) bundler, the logs must only include those relevant to the user operation constructed using the calls submitted via `wallet_sendCalls`. I.e. the logs should not include those from other unrelated user operations submitted in the same bundle.

Expand All @@ -122,38 +146,63 @@ Returns the status of a call batch that was sent via `wallet_sendCalls`. The ide
type GetCallsParams = string;

Choose a reason for hiding this comment

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

It could make sense to add a 'version' parameter here similar to sendCalls:
https://github.com/ethereum/EIPs/pull/8826/files#diff-7a494500c37dc4b57613207d62874322198a4ced215f4a0457a0af908bb6364eR88

This would make updating to the new proposed schema much easier to handle for folks who have already implemented the previously-proposed version

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. Added here:
ddf53b1


type GetCallsResult = {
status: 'PENDING' | 'CONFIRMED';
id: `0x${string}`;
chainId?: `0x${string}`;
status: number; // See "Status Codes"
receipts?: {
logs: {
address: `0x${string}`;
data: `0x${string}`;
topics: `0x${string}`[];
}[];
status: `0x${string}`; // Hex 1 or 0 for success or failure, respectively
chainId: `0x${string}`;
blockHash: `0x${string}`;
blockNumber: `0x${string}`;
gasUsed: `0x${string}`;
transactionHash: `0x${string}`;
}[];
capabilities?: Record<string, any> | undefined;
};
```

##### Status Codes for `status` field

The purpose of the `status` field is to provide a short summary of the current status of the batch.
It provides some off-chain context to the array of inner transaction `receipts`.

| Code | Description |
|------|-------------|
| 100 | Batch has been received by the wallet but has not completed execution onchain (pending) |
| 200 | Batch has been included onchain without reverts, receipts array contains info of all calls (confirmed) |
| 400 | Batch has not been included onchain and wallet will not retry (offchain failure) |
| 500 | Batch reverted completely and only changes related to gas charge may have been included onchain (chain rules failure) |
Copy link
Contributor

Choose a reason for hiding this comment

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

What code covers the case of some calls being included and some reverting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a 600 status code, what do you think? We can also make it, say, 501.
7701a64


Status codes follow these categories:

* 1xx: Pending states
* 2xx: Confirmed states
* 4xx: Offchain failures
* 5xx: Chain rules failures

More specific status codes within these categories should be proposed and agreed upon in separate ERCs.

##### `wallet_getCallsStatus` Example Parameters

As with the return value of `wallet_sendCalls`, the batch identifier may be any string.
The `id` batch identifier is a unique 64 bytes represented as a hex encoded string returned from `wallet_sendCalls`.

```json
[
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
"0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
]
```

##### `wallet_getCallsStatus` Example Return Value

```json
{
"status": "CONFIRMED",
"chainId": "0x01",
"id": "0x00000000000000000000000000000000000000000000000000000000000000000e670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331",
"status": 200,
"receipts": [
{
"logs": [
Expand All @@ -166,7 +215,6 @@ As with the return value of `wallet_sendCalls`, the batch identifier may be any
}
],
"status": "0x1",
"chainId": "0x01",
"blockHash": "0xf19bbafd9fd0124ec110b848e8de4ab4f62bf60c189524e54213285e7f540d4a",
"blockNumber": "0xabcd",
"gasUsed": "0xdef",
Expand All @@ -178,7 +226,7 @@ As with the return value of `wallet_sendCalls`, the batch identifier may be any

### `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.
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 for a known `id` batch identifier. If the identifier is not known, or in case of any other failure to execute `wallet_showCallsStatus` returns an RPC call error.

#### `wallet_showCallsStatus` RPC Specification

Expand All @@ -191,14 +239,12 @@ type ShowCallsParams = string; // Call bundle identifier returned by wallet_send
This method accepts a call bundle identifier returned by a `wallet_sendCalls` call.

```json
[
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
]
["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"]
```

### `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](#privacy-considerations).
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 discovering features, see the ["Privacy Considerations" section](#privacy-considerations).

This method SHOULD return an error if the user has not already authorized a connection between the application and the requested address.
Copy link
Contributor

Choose a reason for hiding this comment

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

What error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no definition of specific errors or error codes for any of the APIs, we could either define all of them explicitly or leave it to the wallets. Should we?

Copy link
Contributor

Choose a reason for hiding this comment

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

for this one specifically i would suggest 4100 unauthorized. i dont think any others need to be defined ? as i believe they are covered by the other 1193 errors + getCallsStatus errors

Copy link
Contributor Author

Choose a reason for hiding this comment

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


Expand All @@ -214,15 +260,15 @@ Capabilities are returned in key/value pairs, with the key naming a capability a
Capabilities are nested in per-chain objects because wallets may support different capabilities across multiple chains authorized in a given session.

```typescript
type GetCapabilitiesParams = [`0x${string}`]; // Wallet address
type GetCapabilitiesParams = [`0x${string}`, [`0x${string}`]]; // Wallet address, array of queried chain ids (optional)

type GetCapabilitiesResult = Record<`0x${string}`, <Record<string, any>>; // Hex chain id
```

##### `wallet_getCapabilities` Example Parameters

```json
["0xd46e8dd67c5d32be8058bb8eb970870f07244567"]
["0xd46e8dd67c5d32be8058bb8eb970870f07244567", ["0x2105", "0x14A34"]]
```

##### `wallet_getCapabilities` Example Return Value
Expand All @@ -247,43 +293,6 @@ 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

```typescript
type AtomicBatchCapability = {
supported: true;
};
```

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`

```json
{
"0x2105": {
"atomicBatch": {
"supported": true
},
},
"0x14A34": {
"atomicBatch": {
"supported": true
}
}
}
```

## Rationale

### On Naming
Expand All @@ -294,9 +303,7 @@ We also debated whether the methods should be called `wallet_sendTransaction`, `

### 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.
The `wallet_sendCalls` method accepts an array of `calls` and by default requires that these calls be executed as part of a single transaction. That said, we expect that in some cases app developers might want to submit batched calls if and only if they can be executed non-atomically. This would enable EOA wallets to accept multiple calls as well over the same interface. A definition of this behaviour may be proposed as a separate capability ERC.

### Call Gas Limit

Expand All @@ -308,7 +315,7 @@ Wallets that do not support the methods defined here SHOULD return error respons

## 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.
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. App developers MUST NOT assume that all calls will be sent in a single transaction.
Copy link
Contributor

Choose a reason for hiding this comment

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

MUST submit multiple calls as an atomic unit in a single transaction

This can be removed, but I'll steal it for flow-control


### Privacy Considerations

Expand Down
Loading