From 96309fb8ef8841bc6906226fd64b287b08f90200 Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Sun, 11 Jan 2026 20:54:54 -0700
Subject: [PATCH 1/3] fix: Update 8021 docs to include info for wallet
providers
---
.../core/capabilities/dataSuffix.mdx | 110 ++++++++++++++++++
.../reference/core/capabilities/overview.mdx | 1 +
docs/base-chain/quickstart/builder-codes.mdx | 11 +-
docs/docs.json | 3 +-
4 files changed, 119 insertions(+), 6 deletions(-)
create mode 100644 docs/base-account/reference/core/capabilities/dataSuffix.mdx
diff --git a/docs/base-account/reference/core/capabilities/dataSuffix.mdx b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
new file mode 100644
index 000000000..305586e13
--- /dev/null
+++ b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
@@ -0,0 +1,110 @@
+---
+title: "dataSuffix"
+description: "Append arbitrary data to transaction calldata for attribution tracking"
+---
+
+Defined in [ERC-8021](https://eip.tools/eip/8021)
+
+
+The dataSuffix capability allows apps to append arbitrary hex-encoded bytes to transaction calldata. This enables attribution tracking, allowing platforms to identify which app originated a transaction and distribute rewards accordingly.
+
+
+## Parameters
+
+
+Hex-encoded bytes to append to the transaction calldata. This value is appended to the end of the calldata for each call in the batch.
+
+
+
+When `true`, the wallet may ignore the capability if it doesn't support it. When `false` or omitted, the wallet must support the capability or reject the request.
+
+
+## Type Definition
+
+```typescript
+type DataSuffixCapability = {
+ value: `0x${string}`;
+ optional?: boolean;
+}
+```
+
+## Example Usage
+
+```typescript Example
+const result = await provider.request({
+ method: "wallet_sendCalls",
+ params: [{
+ version: "1.0",
+ chainId: "0x2105", // Base mainnet
+ from: userAddress,
+ calls: [
+ {
+ to: contractAddress,
+ value: "0x0",
+ data: encodedFunctionCall
+ }
+ ],
+ capabilities: {
+ dataSuffix: {
+ value: "0x1234567890abcdef1234567890abcdef", // Your attribution suffix
+ optional: true // Wallet can proceed even if it doesn't support dataSuffix
+ }
+ }
+ }]
+});
+```
+
+## Primary Use Case: Builder Codes
+
+The primary use case for `dataSuffix` is [Builder Codes](/base-chain/quickstart/builder-codes) attribution. Builder Codes are unique identifiers that allow apps to receive attribution for onchain activity they generate.
+
+When you register on [base.dev](https://base.dev), you receive a Builder Code that can be encoded as a `dataSuffix`.
+
+```typescript
+// Example: Using Builder Code with dataSuffix
+const builderCodeSuffix = "0x..."; // Provided by base.dev
+
+await provider.request({
+ method: "wallet_sendCalls",
+ params: [{
+ version: "1.0",
+ chainId: "0x2105",
+ from: userAddress,
+ calls: [{
+ to: contractAddress,
+ value: "0x0",
+ data: swapCallData
+ }],
+ capabilities: {
+ dataSuffix: {
+ value: builderCodeSuffix
+ }
+ }
+ }]
+});
+```
+
+For complete Builder Codes integration instructions, see the [Builder Codes guide](/base-chain/quickstart/builder-codes).
+
+## How It Works
+
+When a wallet receives a `dataSuffix` capability, the suffix is appended to `userOp.callData`. The suffix bytes are concatenated directly to the end of the calldata, making them available for onchain parsing and attribution.
+
+## Best Practices
+
+1. **Use with Builder Codes**: Register on [base.dev](https://base.dev) to get your Builder Code for proper attribution
+2. **Set optional appropriately**: Use `optional: true` if your app can function without attribution tracking
+3. **Keep suffixes small**: Larger suffixes increase gas costs
+
+
+For wallet developers implementing dataSuffix support, see the [For Wallet Developers](/base-chain/quickstart/builder-codes#for-wallet-developers) section in the Builder Codes guide.
+
+
+## Related Capabilities
+
+- [paymasterService](/base-account/reference/core/capabilities/paymasterService) - Combine with sponsored transactions
+- [atomic](/base-account/reference/core/capabilities/atomic) - Use with atomic batch transactions
+
+import PolicyBanner from "/snippets/PolicyBanner.mdx";
+
+
diff --git a/docs/base-account/reference/core/capabilities/overview.mdx b/docs/base-account/reference/core/capabilities/overview.mdx
index 8388c89de..4a5acb33b 100644
--- a/docs/base-account/reference/core/capabilities/overview.mdx
+++ b/docs/base-account/reference/core/capabilities/overview.mdx
@@ -32,6 +32,7 @@ const baseCapabilities = capabilities["0x2105"]; // Base mainnet chain ID
| [paymasterService](/base-account/reference/core/capabilities/paymasterService) | `wallet_sendCalls` | Gasless transactions |
| [flowControl](/base-account/reference/core/capabilities/flowControl) | `wallet_sendCalls` | Flow control |
| [datacallback](/base-account/reference/core/capabilities/datacallback) | `wallet_sendCalls` | Data callback |
+| [dataSuffix](/base-account/reference/core/capabilities/dataSuffix) | `wallet_sendCalls` | Transaction attribution |
## Using with wallet_connect
diff --git a/docs/base-chain/quickstart/builder-codes.mdx b/docs/base-chain/quickstart/builder-codes.mdx
index bf3c5b456..77bee9166 100644
--- a/docs/base-chain/quickstart/builder-codes.mdx
+++ b/docs/base-chain/quickstart/builder-codes.mdx
@@ -33,11 +33,12 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
- Your wallet should accept a `dataSuffix` string in the `capabilities` object of `wallet_sendCalls`.
+ Your wallet should accept a `dataSuffix` object in the `capabilities` object of `wallet_sendCalls`.
```typescript lines
- interface DataSuffixCapability {
- dataSuffix: string; // hex-encoded bytes provided by the app
+ type DataSuffixCapability = {
+ value: `0x${string}`; // hex-encoded bytes provided by the app
+ optional?: boolean; // whether the capability is optional
}
```
@@ -53,7 +54,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
```typescript lines
// Minimal example for EOA
function applySuffixToEOA(tx, capabilities) {
- const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix
+ const suffix = capabilities.dataSuffix?.value
if (!suffix) return tx
return {
@@ -70,7 +71,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
```typescript lines
// Minimal example for ERC-4337
function applySuffixToUserOp(userOp, capabilities) {
- const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix
+ const suffix = capabilities.dataSuffix?.value
if (!suffix) return userOp
return {
diff --git a/docs/docs.json b/docs/docs.json
index dccc09947..6bf263c1f 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -341,7 +341,8 @@
"base-account/reference/core/capabilities/flowControl",
"base-account/reference/core/capabilities/paymasterService",
"base-account/reference/core/capabilities/auxiliaryFunds",
- "base-account/reference/core/capabilities/datacallback"
+ "base-account/reference/core/capabilities/datacallback",
+ "base-account/reference/core/capabilities/dataSuffix"
]
}
]
From 1c6e185e7645dbd324d42c57be53b48278b02cee Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Sun, 11 Jan 2026 21:09:19 -0700
Subject: [PATCH 2/3] Remove unnecessary comment
---
docs/base-account/reference/core/capabilities/dataSuffix.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/base-account/reference/core/capabilities/dataSuffix.mdx b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
index 305586e13..e4a9fa128 100644
--- a/docs/base-account/reference/core/capabilities/dataSuffix.mdx
+++ b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
@@ -35,7 +35,7 @@ const result = await provider.request({
method: "wallet_sendCalls",
params: [{
version: "1.0",
- chainId: "0x2105", // Base mainnet
+ chainId: "0x2105",
from: userAddress,
calls: [
{
From 010abea5a3c42a8090b37c0fada73249a43292de Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Mon, 12 Jan 2026 16:39:45 -0700
Subject: [PATCH 3/3] Update dataSuffix docs formatting
---
.../core/capabilities/dataSuffix.mdx | 103 +++++++++++++-----
1 file changed, 75 insertions(+), 28 deletions(-)
diff --git a/docs/base-account/reference/core/capabilities/dataSuffix.mdx b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
index e4a9fa128..53f70d472 100644
--- a/docs/base-account/reference/core/capabilities/dataSuffix.mdx
+++ b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
@@ -19,50 +19,100 @@ Hex-encoded bytes to append to the transaction calldata. This value is appended
When `true`, the wallet may ignore the capability if it doesn't support it. When `false` or omitted, the wallet must support the capability or reject the request.
-## Type Definition
+## Returns
-```typescript
-type DataSuffixCapability = {
- value: `0x${string}`;
- optional?: boolean;
-}
-```
+
+The data suffix capability configuration for the specified chain.
+
+
+
+Indicates whether the wallet supports appending data suffixes to transaction calldata.
+
+
+
## Example Usage
-```typescript Example
+
+```typescript Check DataSuffix Support
+const capabilities = await provider.request({
+ method: 'wallet_getCapabilities',
+ params: [userAddress]
+});
+
+const dataSuffixSupport = capabilities["0x2105"]?.dataSuffix;
+```
+
+```typescript Send Transaction with DataSuffix
const result = await provider.request({
method: "wallet_sendCalls",
params: [{
version: "1.0",
chainId: "0x2105",
from: userAddress,
- calls: [
- {
- to: contractAddress,
- value: "0x0",
- data: encodedFunctionCall
- }
- ],
+ calls: [{
+ to: "0x1234567890123456789012345678901234567890",
+ value: "0x0",
+ data: "0xa9059cbb000000000000000000000000..."
+ }],
capabilities: {
dataSuffix: {
- value: "0x1234567890abcdef1234567890abcdef", // Your attribution suffix
- optional: true // Wallet can proceed even if it doesn't support dataSuffix
+ value: "0x1234567890abcdef1234567890abcdef",
+ optional: true
}
}
}]
});
```
+
+
+
+```json Capability Response (Supported)
+{
+ "0x2105": {
+ "dataSuffix": {
+ "supported": true
+ }
+ }
+}
+```
-## Primary Use Case: Builder Codes
+```json Capability Response (Unsupported)
+{
+ "0x2105": {
+ "dataSuffix": {
+ "supported": false
+ }
+ }
+}
+```
+
-The primary use case for `dataSuffix` is [Builder Codes](/base-chain/quickstart/builder-codes) attribution. Builder Codes are unique identifiers that allow apps to receive attribution for onchain activity they generate.
+## Error Handling
+
+| Code | Message | Description |
+| ---- | ------- | ----------- |
+| 4100 | Data suffix not supported | Wallet does not support data suffix functionality |
+| 5700 | DataSuffix capability required | Transaction requires dataSuffix but wallet doesn't support it |
+
+## How It Works
+
+When a wallet receives a `dataSuffix` capability, the suffix is appended to `userOp.callData`. The suffix bytes are concatenated directly to the end of the calldata, making them available for onchain parsing and attribution.
+
+## Use Cases
-When you register on [base.dev](https://base.dev), you receive a Builder Code that can be encoded as a `dataSuffix`.
+### Builder Codes Attribution
+
+The primary use case for `dataSuffix` is [Builder Codes](/base-chain/quickstart/builder-codes) attribution. Builder Codes are unique identifiers that allow apps to receive attribution for onchain activity they generate.
```typescript
-// Example: Using Builder Code with dataSuffix
-const builderCodeSuffix = "0x..."; // Provided by base.dev
+import { Attribution } from "ox/erc8021";
+
+// Example: Using Builder Code with dataSuffix.
+// Using the ox/erc8021 package to generate the ERC-8021 suffix from your builder code.
+const builderCodeSuffix = Attribution.toDataSuffix({
+ codes: ['bc_foobar'], // Get your code from base.dev
+});
await provider.request({
method: "wallet_sendCalls",
@@ -77,18 +127,15 @@ await provider.request({
}],
capabilities: {
dataSuffix: {
- value: builderCodeSuffix
+ value: builderCodeSuffix,
+ optional: true
}
}
}]
});
```
-For complete Builder Codes integration instructions, see the [Builder Codes guide](/base-chain/quickstart/builder-codes).
-
-## How It Works
-
-When a wallet receives a `dataSuffix` capability, the suffix is appended to `userOp.callData`. The suffix bytes are concatenated directly to the end of the calldata, making them available for onchain parsing and attribution.
+Register on [base.dev](https://base.dev) to get your Builder Code for proper attribution.
## Best Practices