Skip to content

Commit 459a7e6

Browse files
authored
Update ERC-7836: Add missing sections
Merged by EIP-Bot.
1 parent 3469c1b commit 459a7e6

File tree

1 file changed

+140
-111
lines changed

1 file changed

+140
-111
lines changed

ERCS/erc-7836.md

Lines changed: 140 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -35,34 +35,36 @@ Instructs a Wallet to prepare a call bundle according to the Account's implement
3535
3636
```typescript
3737
type Request = {
38-
method: 'wallet_prepareCalls',
39-
params: [{
40-
// Calls to be executed.
41-
calls: {
42-
to: `0x${string}`;
43-
data?: `0x${string}`;
44-
value?: `0x${string}`;
38+
method: "wallet_prepareCalls";
39+
params: [
40+
{
41+
// Calls to be executed.
42+
calls: {
43+
to: `0x${string}`;
44+
data?: `0x${string}`;
45+
value?: `0x${string}`;
46+
capabilities?: Record<string, any>;
47+
}[];
48+
// Capabilities.
4549
capabilities?: Record<string, any>;
46-
}[];
47-
// Capabilities.
48-
capabilities?: Record<string, any>
49-
// Chain ID of the chain the calls are being submitted to.
50-
chainId: `0x${string}`;
51-
// Sender address.
52-
from?: `0x${string}`;
53-
// Key (hint) that will be used to sign the call bundle.
54-
key?: {
55-
// Whether the digest will be prehashed by the key (default behavior of WebCrypto APIs).
56-
prehash?: boolean,
57-
// Public key.
58-
publicKey: `0x${string}`,
59-
// Key type.
60-
type: 'secp256k1' | 'p256' | 'webauthn-p256'
61-
};
62-
// JSON-RPC method version.
63-
version: string;
64-
}]
65-
}
50+
// Chain ID of the chain the calls are being submitted to.
51+
chainId: `0x${string}`;
52+
// Sender address.
53+
from?: `0x${string}`;
54+
// Key (hint) that will be used to sign the call bundle.
55+
key?: {
56+
// Whether the digest will be prehashed by the key (default behavior of WebCrypto APIs).
57+
prehash?: boolean;
58+
// Public key.
59+
publicKey: `0x${string}`;
60+
// Key type.
61+
type: "secp256k1" | "p256" | "webauthn-p256";
62+
};
63+
// JSON-RPC method version.
64+
version: string;
65+
}
66+
];
67+
};
6668
```
6769

6870
#### Response
@@ -72,52 +74,57 @@ type Request = {
7274
```typescript
7375
type Response = {
7476
// Capabilities to be forwarded to `wallet_sendPreparedCalls`.
75-
capabilities: Record<string, any>
77+
capabilities: Record<string, any>;
7678
// Chain ID of the chain the calls are being submitted to.
77-
chainId: `0x${string}`
78-
// Data specific to the Wallet to be forwarded to `wallet_sendPreparedCalls`
79+
chainId: `0x${string}`;
80+
// Data specific to the Wallet to be forwarded to `wallet_sendPreparedCalls`
7981
// (e.g. ERC-4337 UserOperation or alternative).
80-
context: unknown
82+
context: unknown;
8183
// Key (hint) that will be used to sign the call bundle.
8284
key?: {
8385
// Whether the digest will be prehashed by the key (default behavior of WebCrypto APIs).
84-
prehash: boolean,
86+
prehash: boolean;
8587
// Public key.
86-
publicKey: `0x${string}`,
88+
publicKey: `0x${string}`;
8789
// Key type.
88-
type: 'secp256k1' | 'p256' | 'webauthn-p256' | 'webcrypto-p256'
89-
},
90+
type: "secp256k1" | "p256" | "webauthn-p256" | "webcrypto-p256";
91+
};
9092
// Digest of the call bundle to sign over.
91-
digest: `0x${string}`
93+
digest: `0x${string}`;
9294
// JSON-RPC method version.
93-
version: string
94-
}
95+
version: string;
96+
};
9597
```
9698

9799
#### Example
98100

99101
```typescript
100102
const response = await provider.request({
101-
method: 'wallet_prepareCalls',
102-
params: [{
103-
calls: [{
104-
to: '0xcafebabecafebabecafebabecafebabecafebabe',
105-
data: '0xdeadbeef',
106-
}],
107-
capabilities: {
108-
paymasterService: {
109-
url: 'https://...',
103+
method: "wallet_prepareCalls",
104+
params: [
105+
{
106+
calls: [
107+
{
108+
to: "0xcafebabecafebabecafebabecafebabecafebabe",
109+
data: "0xdeadbeef",
110+
},
111+
],
112+
capabilities: {
113+
paymasterService: {
114+
url: "https://...",
115+
},
110116
},
117+
chainId: "0x1",
118+
key: {
119+
prehash: false,
120+
publicKey:
121+
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
122+
type: "p256",
123+
},
124+
version: "1",
111125
},
112-
chainId: '0x1',
113-
key: {
114-
prehash: false,
115-
publicKey: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
116-
type: 'p256',
117-
},
118-
version: '1',
119-
}]
120-
})
126+
],
127+
});
121128
/**
122129
* {
123130
* capabilities: {
@@ -140,38 +147,40 @@ const response = await provider.request({
140147

141148
### `wallet_sendPreparedCalls`
142149

143-
Instructs a Wallet to execute a prepared call bundle (response of `wallet_prepareCalls`) with an accompanying `signature`.
150+
Instructs a Wallet to execute a prepared call bundle (response of `wallet_prepareCalls`) with an accompanying `signature`.
144151

145152
#### Parameters
146153

147154
> The request is identical to the response of `wallet_prepareCalls`, except that it includes a `signature`.
148155
149156
```typescript
150157
type Request = {
151-
method: 'wallet_sendPreparedCalls',
152-
params: [{
153-
// Capabilities.
154-
capabilities: Record<string, any>
155-
// Chain ID of the chain the calls are being submitted to.
156-
chainId: `0x${string}`
157-
// Data specific to the Wallet from the `wallet_prepareCalls` response.
158-
// (e.g. ERC-4337 UserOperation or alternative).
159-
context: unknown
160-
// Key that was used to sign the call bundle.
161-
key: {
162-
// Whether the digest will be prehashed by the key (default behavior of WebCrypto APIs).
163-
prehash?: boolean,
164-
// Public key.
165-
publicKey: `0x${string}`,
166-
// Key type.
167-
type: 'secp256k1' | 'p256' | 'webauthn-p256' | 'webcrypto-p256'
168-
},
169-
// Signature of the call bundle.
170-
signature: `0x${string}`
171-
// JSON-RPC method version.
172-
version: string
173-
}]
174-
}
158+
method: "wallet_sendPreparedCalls";
159+
params: [
160+
{
161+
// Capabilities.
162+
capabilities: Record<string, any>;
163+
// Chain ID of the chain the calls are being submitted to.
164+
chainId: `0x${string}`;
165+
// Data specific to the Wallet from the `wallet_prepareCalls` response.
166+
// (e.g. ERC-4337 UserOperation or alternative).
167+
context: unknown;
168+
// Key that was used to sign the call bundle.
169+
key: {
170+
// Whether the digest will be prehashed by the key (default behavior of WebCrypto APIs).
171+
prehash?: boolean;
172+
// Public key.
173+
publicKey: `0x${string}`;
174+
// Key type.
175+
type: "secp256k1" | "p256" | "webauthn-p256" | "webcrypto-p256";
176+
};
177+
// Signature of the call bundle.
178+
signature: `0x${string}`;
179+
// JSON-RPC method version.
180+
version: string;
181+
}
182+
];
183+
};
175184
```
176185

177186
#### Response
@@ -180,45 +189,52 @@ type Request = {
180189
181190
```typescript
182191
type Response = {
183-
id: string,
184-
capabilities: Record<string, any>
185-
}
192+
id: string;
193+
capabilities: Record<string, any>;
194+
};
186195
```
187196

188197
#### Example
189198

190199
```typescript
191200
const { digest, ...request } = await provider.request({
192-
method: 'wallet_prepareCalls',
193-
params: [{
194-
calls: [{
195-
to: '0xcafebabecafebabecafebabecafebabecafebabe',
196-
data: '0xdeadbeef',
197-
}],
198-
capabilities: {
199-
paymasterService: {
200-
url: 'https://...',
201+
method: "wallet_prepareCalls",
202+
params: [
203+
{
204+
calls: [
205+
{
206+
to: "0xcafebabecafebabecafebabecafebabecafebabe",
207+
data: "0xdeadbeef",
208+
},
209+
],
210+
capabilities: {
211+
paymasterService: {
212+
url: "https://...",
213+
},
201214
},
215+
chainId: "0x1",
216+
key: {
217+
prehash: false,
218+
publicKey:
219+
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
220+
type: "p256",
221+
},
222+
version: "1",
202223
},
203-
chainId: '0x1',
204-
key: {
205-
prehash: false,
206-
publicKey: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
207-
type: 'p256',
208-
},
209-
version: '1',
210-
}]
211-
})
224+
],
225+
});
212226

213-
const signature = p256.sign(digest, privateKey)
227+
const signature = p256.sign(digest, privateKey);
214228

215229
const response = await provider.request({
216-
method: 'wallet_sendPreparedCalls',
217-
params: [{
218-
...request,
219-
signature
220-
}]
221-
})
230+
method: "wallet_sendPreparedCalls",
231+
params: [
232+
{
233+
...request,
234+
signature,
235+
},
236+
],
237+
});
222238
/**
223239
* [
224240
* {
@@ -238,11 +254,24 @@ Surfacing the prepared calls should be relatively simple for wallets, who alread
238254

239255
## Backwards Compatibility
240256

241-
TBD <!-- TODO -->
257+
This specification is currently compatible with EIP-5792 and does not introduce breaking changes to existing `wallet_sendCalls` flows.
258+
259+
- It does not modify or deprecate `wallet_sendCalls`; wallets compliant with EIP-5792 continue to work unchanged.
260+
- `wallet_prepareCalls` mirrors the `wallet_sendCalls` request shape and returns values intended to be forwarded to `wallet_sendPreparedCalls`, preserving field formats such as `capabilities`, `chainId`, `context`, and `version`.
261+
- `wallet_sendPreparedCalls` consumes the same data the wallet would otherwise construct internally for EIP-5792, with the addition of an externally produced `signature`.
262+
- Any additional key types or hints (e.g., WebCrypto/WebAuthn variants) are optional and do not affect EIP-5792 behavior.
242263

243264
## Security Considerations
244265

245-
Needs discussion. <!-- TODO -->
266+
- Key authorization and scope: Wallets MUST verify that the provided `key.publicKey` is authorized for the account and that the requested `capabilities` are within that key’s permissions (scopes, limits, validity windows).
267+
268+
- Prehashing consistency: Honor `key.prehash` consistently. A mismatch between signer and verifier (e.g., double-hashing vs prehashed input) can cause verification failures. Wallets SHOULD fix the hash function per key type.
269+
270+
- Preparation-to-execution linkage: Wallets SHOULD ensure `wallet_sendPreparedCalls` corresponds to a `digest` they could have produced (e.g., by recomputing it) and MAY track a preparation identifier and/or validity window to mitigate long-lived replay.
271+
272+
- WebAuthn/origin considerations: For `webauthn-p256`, prefer user-verification and origin-bound credentials. Applications SHOULD keep session keys non-extractable and hardware-backed where available, and avoid presenting opaque digests for end-user approval.
273+
274+
- Resource usage and DoS: Wallets MAY rate-limit `wallet_prepareCalls`, cap bundle sizes, and validate inputs early to avoid expensive context generation for malformed or adversarial requests.
246275

247276
## Copyright
248277

0 commit comments

Comments
 (0)