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 00000000..53f70d47
--- /dev/null
+++ b/docs/base-account/reference/core/capabilities/dataSuffix.mdx
@@ -0,0 +1,157 @@
+---
+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.
+
+
+## Returns
+
+
+The data suffix capability configuration for the specified chain.
+
+
+
+Indicates whether the wallet supports appending data suffixes to transaction calldata.
+
+
+
+
+## Example Usage
+
+
+```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: "0x1234567890123456789012345678901234567890",
+ value: "0x0",
+ data: "0xa9059cbb000000000000000000000000..."
+ }],
+ capabilities: {
+ dataSuffix: {
+ value: "0x1234567890abcdef1234567890abcdef",
+ optional: true
+ }
+ }
+ }]
+});
+```
+
+
+
+```json Capability Response (Supported)
+{
+ "0x2105": {
+ "dataSuffix": {
+ "supported": true
+ }
+ }
+}
+```
+
+```json Capability Response (Unsupported)
+{
+ "0x2105": {
+ "dataSuffix": {
+ "supported": false
+ }
+ }
+}
+```
+
+
+## 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
+
+### 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
+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",
+ params: [{
+ version: "1.0",
+ chainId: "0x2105",
+ from: userAddress,
+ calls: [{
+ to: contractAddress,
+ value: "0x0",
+ data: swapCallData
+ }],
+ capabilities: {
+ dataSuffix: {
+ value: builderCodeSuffix,
+ optional: true
+ }
+ }
+ }]
+});
+```
+
+Register on [base.dev](https://base.dev) to get your Builder Code for proper 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 8388c89d..4a5acb33 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 bf3c5b45..77bee916 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 dccc0994..6bf263c1 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"
]
}
]