Skip to content

Commit 77d48e1

Browse files
Remove Experimental tag from SendCalls (#670)
* Add builder code docs * Update docs/base-chain/quickstart/builder-codes.mdx Co-authored-by: Conner Swenberg <cls364@cornell.edu> * update to use only builder code * update to coming soon with callout at the top of the document * remove experimental from usesendcalls --------- Co-authored-by: Conner Swenberg <cls364@cornell.edu>
1 parent 81e644a commit 77d48e1

File tree

2 files changed

+344
-2
lines changed

2 files changed

+344
-2
lines changed

docs/base-chain/quickstart/builder-codes.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ Integrating Builder Codes requires appending a suffix—provided by Base—to yo
2424

2525
<Tabs>
2626
<Tab title="Wagmi (Recommended)">
27-
Use the `useSendCalls` hook from Wagmi's experimental features to pass the `dataSuffix` capability.
27+
Use the `useSendCalls` hook from Wagmi's features to pass the `dataSuffix` capability.
2828

2929
```typescript lines highlight={14-16}
30-
import { useSendCalls } from 'wagmi/experimental'
30+
import { useSendCalls } from 'wagmi'
3131
import { Attribution } from 'ox/erc8021'
3232

3333
// Your builder code provided by base.dev

tmp-builder-codes-outline.mdx

Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
# Builder Codes Implementation
2+
3+
# Implementation for Apps
4+
## **1\. Get your Builder Code \+ Suffix**
5+
6+
When you register on **base.dev**, we give you:
7+
8+
* **Builder Code** → a random string (e.g., `"k3p9da"`)
9+
* **ERC-8021 Suffix** → already fully encoded as a hex string (e.g., `"0x…"`)
10+
11+
You do **not** build, validate, or encode anything — you just use the suffix we provide.
12+
13+
## **2\. Append the suffix to all transactions**
14+
15+
### **A. EOA Transactions**
16+
17+
If your app sends a normal `eth_sendTransaction`:
18+
19+
`tx.data = tx.data + dataSuffix;`
20+
21+
### **B. Smart Account / ERC-4337 UserOps**
22+
23+
If your app constructs User Operations:
24+
25+
`userOp.callData = userOp.callData + dataSuffix;`
26+
27+
Smart accounts require putting the suffix inside the `callData` of the userOp.
28+
29+
### **C. Using `wallet_sendCalls` (ERC-5792) — Recommended**
30+
31+
The simplest and most reliable way.
32+
33+
Pass the suffix through the capability:
34+
35+
`{`
36+
`"capabilities": [`
37+
`{ "dataSuffix": "0x..." }`
38+
`]`
39+
`}`
40+
41+
Wallets automatically attach it to the correct place (EOA or 4337).
42+
43+
## **3\. No other changes needed**
44+
45+
You **do not** need to:
46+
47+
* Understand the random code
48+
* Decode or encode suffix bytes
49+
* Check schema IDs
50+
* Interact with the registry
51+
* Change your smart contracts
52+
* Modify backend systems
53+
54+
**Just attach the suffix. Everything else is standardized and handled by wallets \+ Base.dev.**
55+
56+
## **🧪 Minimal Example**
57+
58+
`const calls = [{`
59+
`to: contract,`
60+
`data: calldata`
61+
`}];`
62+
63+
`wallet_sendCalls({`
64+
`calls,`
65+
`capabilities: [`
66+
`{ dataSuffix } // provided by base.dev`
67+
`]`
68+
`});`
69+
70+
## **🎉 You’re Done**
71+
72+
Once you add the suffix:
73+
74+
* Your app is fully ERC-8021 compliant
75+
* Your activity is attributed onchain
76+
* You unlock analytics, rewards, rankings, and future incentives
77+
* Wallets and chains can reliably recognize your app
78+
79+
**We give you a random code.**
80+
**We give you the suffix.**
81+
**You attach it.**
82+
**That’s it.**
83+
84+
## **⚡️ Simple Integration Guide (Wagmi \+ ERC-8021 Capability)**
85+
86+
Below is a dead-simple example of how an app attaches the ERC-8021 suffix using wagmi.
87+
88+
Assume:
89+
90+
`const dataSuffix = "0x1234abcd..."; // provided by base.dev`
91+
92+
## **1\. Using wagmi’s `sendCalls` (ERC-5792)**
93+
94+
*(Recommended path — shortest, safest, wallet-native)*
95+
96+
`import { useSendCalls } from 'wagmi/experimental'`
97+
98+
`const dataSuffix = "0x1234abcd..." // provided by base.dev`
99+
100+
`function SendTx() {`
101+
`const { sendCalls } = useSendCalls()`
102+
103+
`async function submit() {`
104+
`await sendCalls({`
105+
`calls: [`
106+
`{`
107+
`to: "0xYourContract",`
108+
`data: "0xYourCalldata"`
109+
`}`
110+
`],`
111+
`capabilities: [`
112+
`{`
113+
`dataSuffix // ERC-8021 capability`
114+
`}`
115+
`]`
116+
`})`
117+
`}`
118+
119+
`return <button onClick={submit}>Send</button>`
120+
`}`
121+
122+
That’s it. No suffix encoding, no registry lookups, no 4337 branching — wagmi \+ the wallet handle all of it.
123+
124+
## **2\. If you’re using viem directly**
125+
126+
`import { walletClient } from './client'`
127+
128+
`const dataSuffix = "0x1234abcd..."`
129+
130+
`await walletClient.sendCalls({`
131+
`calls: [`
132+
`{`
133+
`to: "0xYourContract",`
134+
`data: "0xYourCalldata"`
135+
`}`
136+
`],`
137+
`capabilities: [`
138+
`{ dataSuffix }`
139+
`]`
140+
`})`
141+
142+
## **3\. If you’re still using `writeContract` (EOA only)**
143+
144+
*(Not recommended, but supported)*
145+
You can manually append to calldata:
146+
147+
`await writeContract({`
148+
`address: "0xYourContract",`
149+
`abi,`
150+
`functionName: "yourFn",`
151+
`args: [a, b, c],`
152+
`// WAGMI builds calldata for you; we append the suffix`
153+
`dataSuffix,`
154+
`})`
155+
156+
If your wagmi version doesn’t expose a `dataSuffix` field, simply concatenate manually:
157+
158+
`const encoded = encodeFunctionData({`
159+
`abi,`
160+
`functionName: "yourFn",`
161+
`args: [a, b, c],`
162+
`})`
163+
164+
`const dataWithSuffix = encoded + dataSuffix.slice(2)`
165+
166+
`await sendTransaction({`
167+
`to: "0xYourContract",`
168+
`data: dataWithSuffix,`
169+
`})`
170+
171+
## **4\. ERC-4337 (UserOps) — only if you construct them manually**
172+
173+
Almost no apps do this directly. But if they do:
174+
175+
`userOp.callData = userOp.callData + dataSuffix.slice(2)`
176+
177+
And send it through your bundler or wallet SDK.
178+
179+
## **💡 Summary for builders**
180+
181+
**You don’t need to understand ERC-8021.**
182+
**You only need your suffix.**
183+
184+
Then:
185+
186+
### **Using wagmi \+ 5792**
187+
188+
`capabilities: [{ dataSuffix }]`
189+
190+
### **Everything else happens automatically.**
191+
192+
# Implementation for Wallets
193+
## **⚡️ ERC-8021 Integration Guide for Wallets**
194+
195+
**Add support for attribution codes with minimal changes.**
196+
197+
This guide shows exactly how to:
198+
199+
1. Accept the `dataSuffix` capability from apps
200+
201+
2. Append the suffix correctly to outgoing transactions
202+
203+
3. Support both EOAs and ERC-4337 smart accounts
204+
205+
4. Do all of the above with almost zero logic or schema awareness
206+
207+
## **1\. Support the ERC-5792 `dataSuffix` capability**
208+
209+
Wallets should accept:
210+
211+
`interface DataSuffixCapability {`
212+
`dataSuffix: string; // hex-encoded bytes`
213+
`}`
214+
215+
This appears inside the `capabilities` array of `wallet_sendCalls`.
216+
217+
**What you must do:**
218+
219+
* Look for any capability object that includes `dataSuffix`
220+
221+
* Extract the hex string
222+
223+
* Store it for use when constructing the transaction or user operation
224+
225+
**No decoding, no validation, no schema handling is required.**
226+
227+
Wallets do *not* need to understand what the suffix means—just pass it through verbatim.
228+
229+
## **2\. Append the suffix to calldata depending on account type**
230+
231+
Wallets only need **one conditional branch**.
232+
233+
## **A. If the user is sending an EOA transaction**
234+
235+
Append the suffix to the transaction `data`:
236+
237+
`tx.data = concat(tx.data, dataSuffix)`
238+
239+
This is literally bytes concatenation.
240+
241+
## **B. If the user is sending an ERC-4337 user operation**
242+
243+
Append the suffix to the **userOp.callData**, not the transaction-level calldata:
244+
245+
`userOp.callData = concat(userOp.callData, dataSuffix)`
246+
247+
This ensures parsers see the suffix where the call is actually executed.
248+
249+
## **C. When using `wallet_sendCalls` (ERC-5792)**
250+
251+
If your wallet supports ERC-5792, this is the recommended path.
252+
253+
Steps:
254+
255+
1. Read `capabilities[]`
256+
257+
2. Extract `dataSuffix`
258+
259+
3. For each call in `calls[]`:
260+
261+
* If EOA → append to `tx.data`
262+
263+
* If 4337 → append to `userOp.callData`
264+
265+
That’s the entire integration.
266+
267+
## **3\. (Optional) Wallet attribution**
268+
269+
Wallets **may** also include *their own attribution code* (their own ERC-8021 suffix):
270+
271+
* Simply prepend the wallet’s own suffix before the app’s
272+
273+
* No interaction is required with apps
274+
275+
* Multi-code support is built into ERC-8021
276+
277+
Example:
278+
279+
`finalSuffix = walletSuffix + appSuffix`
280+
281+
This is fully supported by the standard.
282+
283+
## **4\. Error handling**
284+
285+
Wallets **do not** need to:
286+
287+
* Validate the encoding
288+
289+
* Parse or interpret the suffix
290+
291+
* Query registries
292+
293+
* Reject malformed codes
294+
295+
If the suffix is malformed, apps are the ones losing attribution—not the wallet.
296+
297+
**Safe failure mode:** append whatever is provided.
298+
299+
## **5\. Minimal example (EOA)**
300+
301+
`function applySuffixToEOA(tx, capabilities) {`
302+
`const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix`
303+
`if (!suffix) return tx`
304+
305+
`return {`
306+
`...tx,`
307+
`data: tx.data + suffix.slice(2)`
308+
`}`
309+
`}`
310+
311+
## **6\. Minimal example (ERC-4337)**
312+
313+
`function applySuffixToUserOp(userOp, capabilities) {`
314+
`const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix`
315+
`if (!suffix) return userOp`
316+
317+
`return {`
318+
`...userOp,`
319+
`callData: userOp.callData + suffix.slice(2)`
320+
`}`
321+
`}`
322+
323+
## **7\. Recap: The full wallet responsibility (very small)**
324+
325+
### **✅ Accept the `dataSuffix` capability**
326+
327+
### **✅ Append suffix to calldata**
328+
329+
* EOAs → `tx.data`
330+
331+
* 4337 → `userOp.callData`
332+
333+
### **Optional: Add wallet attribution code**
334+
335+
### **No: parsing, decoding, validation, or registry interaction**
336+
337+
---
338+
339+
## **📌 TL;DR for wallet engineers**
340+
341+
**“If a call has a `dataSuffix`, append it to calldata before sending.**
342+
**Use transaction.data for EOAs, userOp.callData for 4337\. That’s all.”**

0 commit comments

Comments
 (0)