From 39dcf0667555570d57b7d4430be558c488094506 Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Tue, 3 Feb 2026 14:44:53 -0700
Subject: [PATCH 1/3] docs: Update builder code docs to suggest using
dataSuffix at the client level
---
.../builder-codes/builder-codes.mdx | 237 +++++++++++++-----
1 file changed, 180 insertions(+), 57 deletions(-)
diff --git a/docs/base-chain/builder-codes/builder-codes.mdx b/docs/base-chain/builder-codes/builder-codes.mdx
index ce3f27b59..51e7834e3 100644
--- a/docs/base-chain/builder-codes/builder-codes.mdx
+++ b/docs/base-chain/builder-codes/builder-codes.mdx
@@ -5,88 +5,82 @@ description: "Integrate Builder Codes to attribute onchain activity to your app
## What are Builder Codes
-Base Builder Codes are an ERC-721 NFT collection where unique codes (e.g. “abc123”) are minted to help identify builders onchain.
+Base Builder Codes are an ERC-721 NFT collection where unique codes (e.g. "abc123") are minted to help identify builders onchain.
-Each code has associated metadata. Onchain metadata primarily includes a “payout address” where each code declares where potential rewards should be sent to. Offchain metadata includes more details about the app including its name and site.
+Each code has associated metadata. Onchain metadata primarily includes a "payout address" where each code declares where potential rewards should be sent to. Offchain metadata includes more details about the app including its name and site.
## Automatic Builder-Code Attribution on Base
Once your app is registered on [Base.dev](http://base.dev/), the Base App will auto-append your Base Builder Code to transactions its users make in your app (e.g. via your mini app, or the Base App's browser). This powers your onchain analytics in [Base.dev](http://base.dev/) and qualifies you for potential future rewards.
-
## For App Developers
-When you register on [base.dev](https://base.dev/), you will receive a **Builder Code**—a random string (e.g., `bc_b7k3p9da` ) that you'll use to generate your attribution suffix.
+When you register on [base.dev](https://base.dev/), you will receive a **Builder Code**—a random string (e.g., `bc_b7k3p9da`) that you'll use to generate your attribution suffix.
You can find your code anytime under **Settings** → **Builder Code**.
-
-
+The recommended approach is to configure `dataSuffix` at the client level, which automatically appends your Builder Code to all transactions.
+
+
+ Requires [viem](https://viem.sh) version 2.45.0 or higher, or [wagmi](https://wagmi.sh) version 2.17.0 or higher.
+
-This will allow you to append the encoded version of your builder code.
+### Quick setup with Wagmi
- ```bash Terminal
- npm i ox
- ```
-
+
+
+ Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
-
- Navigate to **base.dev > Settings > Builder Codes** to find your unique builder code.
+ ```bash
+ npm i ox wagmi viem
+ ```
-
- Use the `Attribution.toDataSuffix` method from the `ox` library to encode your builder code:
+
+ Add the `dataSuffix` option to your Wagmi config. This automatically appends your Builder Code to all transactions.
- ```ts App.tsx
+ ```ts config.ts
+ import { createConfig, http } from "wagmi";
+ import { base } from "wagmi/chains";
import { Attribution } from "ox/erc8021";
+ // Get your Builder Code from base.dev > Settings > Builder Codes
const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"], // obtained from base.dev > Settings > Builder Codes
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ export const config = createConfig({
+ chains: [base],
+ transports: {
+ [base.id]: http(),
+ },
+ dataSuffix: DATA_SUFFIX,
});
```
-
- Use Wagmi's `useSendCalls` hook with the `dataSuffix` capability to append attribution data to your transactions.
+
+ With the config in place, all transactions automatically include your Builder Code—no changes to your hooks or components. This works with both `useSendTransaction` and `useSendCalls`.
- ```ts App.tsx
- import { useSendCalls } from "wagmi";
+ ```tsx App.tsx
+ import { useSendTransaction } from "wagmi";
import { parseEther } from "viem";
- import { Attribution } from "ox/erc8021";
- const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"],
- });
-
- function App() {
- const { sendCalls } = useSendCalls();
+ function SendButton() {
+ const { sendTransaction } = useSendTransaction();
return (
);
}
@@ -94,15 +88,144 @@ This will allow you to append the encoded version of your builder code.
+### Quick setup with Viem
+
+
+
+ Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
+
+ ```bash
+ npm i ox viem
+ ```
+
+
+
+ Add the `dataSuffix` option when creating your wallet client. See the [viem wallet client docs](https://viem.sh/docs/clients/wallet) for more configuration options.
+
+ ```ts client.ts
+ import { createWalletClient, http } from "viem";
+ import { base } from "viem/chains";
+ import { Attribution } from "ox/erc8021";
+
+ // Get your Builder Code from base.dev > Settings > Builder Codes
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ export const walletClient = createWalletClient({
+ chain: base,
+ transport: http(),
+ dataSuffix: DATA_SUFFIX,
+ });
+ ```
+
+
+
+ All transactions sent through this client automatically include your Builder Code.
+
+ ```ts
+ import { parseEther } from "viem";
+ import { walletClient } from "./client";
+
+ const hash = await walletClient.sendTransaction({
+ to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
+ value: parseEther("0.01"),
+ });
+ ```
+
+
+
+### Legacy: Per-transaction approach
+
+
+ If you need to append the suffix on a per-transaction basis rather than at the client level, you can pass `dataSuffix` directly to the transaction.
+
+
+
+ ```tsx App.tsx
+ import { useSendTransaction } from "wagmi";
+ import { parseEther } from "viem";
+ import { Attribution } from "ox/erc8021";
+
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ function App() {
+ const { sendTransaction } = useSendTransaction();
+
+ return (
+
+ );
+ }
+ ```
+
+
+ When using `useSendCalls`, pass the suffix via the `capabilities` object. This requires the connected wallet to support the `dataSuffix` capability.
+
+ ```tsx App.tsx
+ import { useSendCalls } from "wagmi";
+ import { parseEther } from "viem";
+ import { Attribution } from "ox/erc8021";
+
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ function App() {
+ const { sendCalls } = useSendCalls();
+
+ return (
+
+ );
+ }
+ ```
+
+
+
+
+### Verify attribution
+
+To confirm your Builder Code is being appended correctly, see [How do I verify that my transaction was properly attributed?](/base-chain/builder-codes/builder-codes-faq#how-do-i-verify-that-my-transaction-was-properly-attributed) in the FAQ.
+
## For Wallet Developers
Wallet providers need to support the `dataSuffix` capability to enable attribution. This involves accepting the capability and appending the suffix to the calldata before signing.
-
+
Your wallet should accept a `dataSuffix` object in the `capabilities` object of `wallet_sendCalls`.
- ```typescript lines
+ ```typescript
type DataSuffixCapability = {
value: `0x${string}`; // hex-encoded bytes provided by the app
optional?: boolean; // whether the capability is optional
@@ -111,14 +234,14 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
-
+
When constructing the transaction or User Operation, extract the `dataSuffix` and append it to the calldata.
Append to `tx.data`.
- ```typescript lines
+ ```typescript
// Minimal example for EOA
function applySuffixToEOA(tx, capabilities) {
const suffix = capabilities.dataSuffix?.value
@@ -135,7 +258,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
Append to `userOp.callData` (not the transaction-level calldata).
- ```typescript lines
+ ```typescript
// Minimal example for ERC-4337
function applySuffixToUserOp(userOp, capabilities) {
const suffix = capabilities.dataSuffix?.value
@@ -152,11 +275,11 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
-
- Wallets may also include their own attribution code (their own ERC-8021 suffix) by simply prepending the wallet’s own suffix before the app’s.
+
+ Wallets may also include their own attribution code (their own ERC-8021 suffix) by prepending the wallet's suffix before the app's.
- * **No interaction required with apps:** The wallet handles this independently.
- * **Multi-code support:** ERC-8021 natively supports multiple attribution codes.
+ - **No interaction required with apps:** The wallet handles this independently.
+ - **Multi-code support:** ERC-8021 natively supports multiple attribution codes.
**Example:**
@@ -191,7 +314,7 @@ Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-sol
-
+
Set `to = BRIDGE_CAMPAIGN_ADDRESS` and attach a call to `Flywheel.send`.
@@ -251,7 +374,7 @@ Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-sol
-
+
[Terminally Onchain](https://terminallyonchain.com/) is a production Next.js app that exposes the bridge via a command terminal UI. Users connect a Solana wallet, type commands such as to bridge and call a contract on Base:
You can use [Terminally Onchain](https://terminallyonchain.com/) to test bridge transactions with Builder Codes like so:
From 3862c220d02586c196f353056db8480cf777efda Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Tue, 3 Feb 2026 14:53:47 -0700
Subject: [PATCH 2/3] Titlecase
---
.../builder-codes/builder-codes.mdx | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/docs/base-chain/builder-codes/builder-codes.mdx b/docs/base-chain/builder-codes/builder-codes.mdx
index 51e7834e3..35a0e3358 100644
--- a/docs/base-chain/builder-codes/builder-codes.mdx
+++ b/docs/base-chain/builder-codes/builder-codes.mdx
@@ -27,10 +27,10 @@ The recommended approach is to configure `dataSuffix` at the client level, which
Requires [viem](https://viem.sh) version 2.45.0 or higher, or [wagmi](https://wagmi.sh) version 2.17.0 or higher.
-### Quick setup with Wagmi
+### Quick Setup with Wagmi
-
+
Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
```bash
@@ -38,7 +38,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
```
-
+
Add the `dataSuffix` option to your Wagmi config. This automatically appends your Builder Code to all transactions.
```ts config.ts
@@ -61,7 +61,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
```
-
+
With the config in place, all transactions automatically include your Builder Code—no changes to your hooks or components. This works with both `useSendTransaction` and `useSendCalls`.
```tsx App.tsx
@@ -88,10 +88,10 @@ The recommended approach is to configure `dataSuffix` at the client level, which
-### Quick setup with Viem
+### Quick Setup with Viem
-
+
Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
```bash
@@ -99,7 +99,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
```
-
+
Add the `dataSuffix` option when creating your wallet client. See the [viem wallet client docs](https://viem.sh/docs/clients/wallet) for more configuration options.
```ts client.ts
@@ -120,7 +120,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
```
-
+
All transactions sent through this client automatically include your Builder Code.
```ts
@@ -135,7 +135,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
-### Legacy: Per-transaction approach
+### Legacy: Per-Transaction Approach
If you need to append the suffix on a per-transaction basis rather than at the client level, you can pass `dataSuffix` directly to the transaction.
@@ -213,7 +213,7 @@ The recommended approach is to configure `dataSuffix` at the client level, which
-### Verify attribution
+### Verify Attribution
To confirm your Builder Code is being appended correctly, see [How do I verify that my transaction was properly attributed?](/base-chain/builder-codes/builder-codes-faq#how-do-i-verify-that-my-transaction-was-properly-attributed) in the FAQ.
@@ -222,7 +222,7 @@ To confirm your Builder Code is being appended correctly, see [How do I verify t
Wallet providers need to support the `dataSuffix` capability to enable attribution. This involves accepting the capability and appending the suffix to the calldata before signing.
-
+
Your wallet should accept a `dataSuffix` object in the `capabilities` object of `wallet_sendCalls`.
```typescript
@@ -234,7 +234,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
-
+
When constructing the transaction or User Operation, extract the `dataSuffix` and append it to the calldata.
@@ -275,7 +275,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
-
+
Wallets may also include their own attribution code (their own ERC-8021 suffix) by prepending the wallet's suffix before the app's.
- **No interaction required with apps:** The wallet handles this independently.
@@ -297,7 +297,7 @@ Wallet providers need to support the `dataSuffix` capability to enable attributi
Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-solana-bridge) via the [`hookData`](https://github.com/base/flywheel/blob/30266bba4649b0eb161e55bfa4755651049a5d1f/src/hooks/BridgeReferralFees.sol#L75) mechanism. Currently available for **Solana → Base** flows only.
-
+
When you register on base.dev, you will find a Builder Code under your app's settings. This is a random string (e.g., k3p9da) that you will use to generate your attribution suffix.
@@ -314,7 +314,7 @@ Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-sol
-
+
Set `to = BRIDGE_CAMPAIGN_ADDRESS` and attach a call to `Flywheel.send`.
@@ -374,7 +374,7 @@ Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-sol
-
+
[Terminally Onchain](https://terminallyonchain.com/) is a production Next.js app that exposes the bridge via a command terminal UI. Users connect a Solana wallet, type commands such as to bridge and call a contract on Base:
You can use [Terminally Onchain](https://terminallyonchain.com/) to test bridge transactions with Builder Codes like so:
From 722fc475ce0f08d97097267b9563d269e902b8c2 Mon Sep 17 00:00:00 2001
From: Dan Cortes <3639170+dgca@users.noreply.github.com>
Date: Tue, 3 Feb 2026 18:40:01 -0700
Subject: [PATCH 3/3] Split buidler code docs to separate pages
---
.../builder-codes/app-developers.mdx | 229 ++++++++
.../builder-codes/bridge-developers.mdx | 177 ++++++
.../builder-codes/builder-codes-faq.mdx | 104 ----
.../builder-codes/builder-codes.mdx | 532 +++---------------
.../builder-codes/wallet-developers.mdx | 80 +++
docs/docs.json | 20 +-
6 files changed, 595 insertions(+), 547 deletions(-)
create mode 100644 docs/base-chain/builder-codes/app-developers.mdx
create mode 100644 docs/base-chain/builder-codes/bridge-developers.mdx
delete mode 100644 docs/base-chain/builder-codes/builder-codes-faq.mdx
create mode 100644 docs/base-chain/builder-codes/wallet-developers.mdx
diff --git a/docs/base-chain/builder-codes/app-developers.mdx b/docs/base-chain/builder-codes/app-developers.mdx
new file mode 100644
index 000000000..0e2cdd70d
--- /dev/null
+++ b/docs/base-chain/builder-codes/app-developers.mdx
@@ -0,0 +1,229 @@
+---
+title: "Builder Codes for App Developers"
+sidebarTitle: "For App Developers"
+description: "Integrate Builder Codes into your app using Wagmi or Viem to attribute onchain activity."
+---
+
+## Automatic Attribution on Base
+
+Once your app is registered on [base.dev](http://base.dev/), the Base App will auto-append your Builder Code to transactions its users make in your app (e.g. via your mini app, or the Base App's browser). This powers your onchain analytics in [base.dev](http://base.dev/) and qualifies you for potential future rewards.
+
+## Integrating Outside the Base App
+
+If users also access your app on the web or through other clients, you'll need to integrate the `dataSuffix` parameter to capture that activity.
+
+When you register on [base.dev](https://base.dev/), you will receive a **Builder Code**—a random string (e.g., `bc_b7k3p9da`) that you'll use to generate your attribution suffix. The recommended approach is to configure `dataSuffix` at the client level, which appends your Builder Code to all transactions.
+
+
+ You can find your code anytime under **Settings** → **Builder Code**.
+
+
+## Quick Setup with Wagmi
+
+
+
+ Install the required packages. Requires viem version `2.45.0` or higher.
+
+ ```bash
+ npm i ox wagmi viem
+ ```
+
+
+
+ Add the `dataSuffix` option to your Wagmi config. This automatically appends your Builder Code to all transactions.
+
+ ```ts config.ts
+ import { createConfig, http } from "wagmi";
+ import { base } from "wagmi/chains";
+ import { Attribution } from "ox/erc8021";
+
+ // Get your Builder Code from base.dev > Settings > Builder Codes
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ export const config = createConfig({
+ chains: [base],
+ transports: {
+ [base.id]: http(),
+ },
+ dataSuffix: DATA_SUFFIX,
+ });
+ ```
+
+
+
+ With the config in place, all transactions automatically include your Builder Code—no changes to your hooks or components. This works with both `useSendTransaction` and `useSendCalls`.
+
+ ```tsx App.tsx
+ import { useSendTransaction } from "wagmi";
+ import { parseEther } from "viem";
+
+ function SendButton() {
+ const { sendTransaction } = useSendTransaction();
+
+ return (
+
+ );
+ }
+ ```
+
+
+
+## Quick Setup with Viem
+
+
+
+ Install the required packages. Requires viem version `2.45.0` or higher.
+
+ ```bash
+ npm i ox viem
+ ```
+
+
+
+ Add the `dataSuffix` option when creating your wallet client. See the [viem wallet client docs](https://viem.sh/docs/clients/wallet) for more configuration options.
+
+ ```ts client.ts
+ import { createWalletClient, http } from "viem";
+ import { base } from "viem/chains";
+ import { Attribution } from "ox/erc8021";
+
+ // Get your Builder Code from base.dev > Settings > Builder Codes
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ export const walletClient = createWalletClient({
+ chain: base,
+ transport: http(),
+ dataSuffix: DATA_SUFFIX,
+ });
+ ```
+
+
+
+ All transactions sent through this client automatically include your Builder Code.
+
+ ```ts
+ import { parseEther } from "viem";
+ import { walletClient } from "./client";
+
+ const hash = await walletClient.sendTransaction({
+ to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
+ value: parseEther("0.01"),
+ });
+ ```
+
+
+
+## Legacy: Per-Transaction Approach
+
+
+ If you need to append the suffix on a per-transaction basis rather than at the client level, you can pass `dataSuffix` directly to the transaction.
+
+
+
+ ```tsx App.tsx
+ import { useSendTransaction } from "wagmi";
+ import { parseEther } from "viem";
+ import { Attribution } from "ox/erc8021";
+
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ function App() {
+ const { sendTransaction } = useSendTransaction();
+
+ return (
+
+ );
+ }
+ ```
+
+
+ When using `useSendCalls`, pass the suffix via the `capabilities` object. This requires the connected wallet to support the `dataSuffix` capability.
+
+ ```tsx App.tsx
+ import { useSendCalls } from "wagmi";
+ import { parseEther } from "viem";
+ import { Attribution } from "ox/erc8021";
+
+ const DATA_SUFFIX = Attribution.toDataSuffix({
+ codes: ["YOUR-BUILDER-CODE"],
+ });
+
+ function App() {
+ const { sendCalls } = useSendCalls();
+
+ return (
+
+ );
+ }
+ ```
+
+
+
+
+## Verify Attribution
+
+To confirm your Builder Code is being appended correctly:
+
+**1. Check base.dev**
+
+- Visit [base.dev](https://base.dev)
+- Select **Onchain** from the transaction type dropdown
+- Under the Total Transactions section, attribution counts increment when transactions with your code are processed
+
+**2. Use a Block Explorer (Basescan, Etherscan, etc.)**
+
+- Find your transaction hash
+- View the input data field
+- Verify the last 16 bytes are the `8021` repeating
+- Decode the suffix to confirm your Builder Code is present
+
+**3. Open Source Tools**
+
+- Use the [Builder Code Validation](https://builder-code-checker.vercel.app/) tool
+- Select transaction type
+- Enter the transaction or UserOperation hash
+- Click the **Check Attribution** button
diff --git a/docs/base-chain/builder-codes/bridge-developers.mdx b/docs/base-chain/builder-codes/bridge-developers.mdx
new file mode 100644
index 000000000..aad5da6b9
--- /dev/null
+++ b/docs/base-chain/builder-codes/bridge-developers.mdx
@@ -0,0 +1,177 @@
+---
+title: "Builder Codes for Bridge Developers"
+sidebarTitle: "For Bridge Developers"
+description: "Integrate Builder Codes with the Base-Solana bridge using hookData."
+---
+
+Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-solana-bridge) via the [`hookData`](https://github.com/base/flywheel/blob/30266bba4649b0eb161e55bfa4755651049a5d1f/src/hooks/BridgeReferralFees.sol#L75) mechanism. Currently available for **Solana → Base** flows only.
+
+
+
+ When you register on base.dev, you will find a Builder Code under your app's settings. This is a random string (e.g., k3p9da) that you will use to generate your attribution suffix.
+
+
+
+ ABI-encode the user address, your code, and fee:
+
+ ```solidity
+ bytes memory hookData = abi.encode(
+ 0xUSER, // destination address on Base (NOT the Twin)
+ 0xBUILDER_CODE, // your builder code in type string memory
+ 100 // feeBps (100 = 1%)
+ );
+ ```
+
+
+
+
+ Set `to = BRIDGE_CAMPAIGN_ADDRESS` and attach a call to `Flywheel.send`.
+
+
+
+ For a bridge with no follow-up call:
+
+ ```
+ to: // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
+ amount: 100
+ call:
+ ty: Call
+ to: // 0x00000F14AD09382841DB481403D1775ADeE1179F on Base Sepolia
+ value: 0
+ data: abi.encodeWithSelector(
+ Flywheel.send.selector,
+ , // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
+ ,
+ hookData
+ )
+ ```
+
+
+ To chain additional calls, use `DelegateCall` with `Multicall`:
+
+ ```solidity
+ Call[] memory calls = new Call[](2);
+
+ // 1) Flywheel attribution (must be first)
+ calls[0] = Call({
+ to: , // 0x00000F14AD09382841DB481403D1775ADeE1179F on Base Sepolia
+ value: 0,
+ data: abi.encodeWithSelector(
+ Flywheel.send.selector,
+ , // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
+ , // e.g. For SOL on Base Sepolia, use 0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC
+ hookData
+ )
+ });
+
+ // 2) Your follow-up call
+ calls[1] = Call({
+ to: ,
+ value: 0,
+ data: abi.encodeWithSelector(YourContract.yourFunction.selector)
+ });
+ ```
+
+ Then set the bridge call to:
+
+ ```
+ call:
+ ty: DelegateCall
+ to: // 0xcA11bde05977b3631167028862bE2a173976CA11 on Base Mainnet
+ data: abi.encodeWithSelector(Multicall.multicall.selector, calls)
+ ```
+
+
+
+
+
+ [Terminally Onchain](https://terminallyonchain.com/) is a production Next.js app that exposes the bridge via a command terminal UI. Users connect a Solana wallet, type commands such as to bridge and call a contract on Base:
+
+ You can use [Terminally Onchain](https://terminallyonchain.com/) to test bridge transactions with Builder Codes like so:
+
+ ```bash
+ bridge 0.0001 sol 0xYOUR_DESTINATION_ADDRESS --with-bc YOUR_BUILDER_CODE --bc-fee YOUR_FEE_BPS
+ ```
+
+ To see how this is implemented, you can take a look at the [Github repo](https://github.com/base/sol2base/blob/e0c283035be1e3e345d329e2d77b05e29a1d38b3/src/components/MainContent.tsx#L667):
+
+ ```typescript sol2base/MainContent.tsx expandable
+ // Constants
+ const BRIDGE_CAMPAIGN_ADDRESS = "0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9";
+ const FLYWHEEL_ADDRESS = "0x00000F14AD09382841DB481403D1775ADeE1179F";
+ const MULTICALL_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
+
+ // Encode hookData: (address user, string code, uint8 feeBps)
+ const buildBuilderHookData = (
+ destination: string,
+ builderCode: string,
+ feeBps: number
+ ) => {
+ const coder = new AbiCoder();
+ return coder.encode(
+ ["address", "string", "uint8"],
+ [destination, builderCode, feeBps]
+ );
+ };
+
+ // Build Flywheel.send call
+ const buildBuilderCall = (
+ destination: string,
+ builderCode: string,
+ feeBps: number,
+ tokenAddress: string
+ ): BaseContractCall => {
+ const hookData = buildBuilderHookData(destination, builderCode, feeBps);
+ const data = encodeFunctionData({
+ abi: FLYWHEEL_ABI,
+ functionName: "send",
+ args: [BRIDGE_CAMPAIGN_ADDRESS, tokenAddress, hookData],
+ });
+ return { type: "call", target: FLYWHEEL_ADDRESS, value: "0", data };
+ };
+
+ // Wrap builder + user calls in Multicall (for chained calls)
+ const buildMulticall = (
+ builder: BaseContractCall,
+ userCall: BaseContractCall
+ ): BaseContractCall => {
+ const data = encodeFunctionData({
+ abi: MULTICALL_ABI,
+ functionName: "multicall",
+ args: [
+ [
+ { target: builder.target, callData: builder.data },
+ { target: userCall.target, callData: userCall.data },
+ ],
+ ],
+ });
+ return { type: "delegatecall", target: MULTICALL_ADDRESS, value: "0", data };
+ };
+
+ // Usage: attach builder code to bridge
+ if (payload.flags.withBc) {
+ const builderCall = buildBuilderCall(
+ destination,
+ builderCode,
+ feeBps,
+ remoteToken
+ );
+ callOption = userCall ? buildMulticall(builderCall, userCall) : builderCall;
+ }
+
+ // Set destination to campaign address when using builder codes
+ const destinationForBridge = builderCode
+ ? BRIDGE_CAMPAIGN_ADDRESS
+ : payload.destination;
+ ```
+
+
+
+
+## Contract Addresses
+
+| Contract | Base Mainnet | Base Sepolia |
+| -------- | ------------ | ------------ |
+| `BRIDGE_CAMPAIGN_ADDRESS` | `0x539A97cc4724d5b2740DB98Bc71445448eFC1Bde` | `0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9` |
+| `FLYWHEEL_ADDRESS` | `0x00000F14AD09382841DB481403D1775ADeE1179F` | `0x00000F14AD09382841DB481403D1775ADeE1179F` |
+| `MULTICALL_ADDRESS` | `0xcA11bde05977b3631167028862bE2a173976CA11` | `0xcA11bde05977b3631167028862bE2a173976CA11` |
diff --git a/docs/base-chain/builder-codes/builder-codes-faq.mdx b/docs/base-chain/builder-codes/builder-codes-faq.mdx
deleted file mode 100644
index 8e36f6242..000000000
--- a/docs/base-chain/builder-codes/builder-codes-faq.mdx
+++ /dev/null
@@ -1,104 +0,0 @@
----
-title: "Builder Codes FAQ"
-description: "Common questions about Builder Codes, ERC-8021 transaction attribution, gas costs, and SDK support on Base."
----
-
-### What is a "Builder Code" and where do I get one?
-
-A **Builder Code** is an ASCII string (like `"baseapp"` or `"bc_xyz456"`) that identifies your application in the ERC-8021 attribution system. When your app's transactions include this code, protocols can identify and reward you.
-
-
- Obtain your Builder Code [here](/base-chain/builder-codes/builder-codes).
-
-
-### What are the benefits of supporting Builder Codes?
-
-- **Rewards:** If your app drives transactions, Builder Codes let Base automatically attribute that usage back to you, unlocking rewards as our program expands.
-- **Analytics:** Developers can reliably track onchain usage, user acquisition, and conversion metrics in Base.dev.
-- **Visibility:** Apps with Builder Codes can show up in discovery surfaces like our App Leaderboards, Base App store, and ecosystem spotlights.
-
-### Do I need to modify my smart contracts to use ERC-8021?
-
-**No.** The attribution suffix is appended to the end of transaction calldata. Smart contracts execute normally and ignore the extra data. Attribution is extracted by offchain indexers after the fact.
-
-This means:
-
-- Any existing smart contract automatically supports ERC-8021
-- No upgrades or redeployments required
-- Zero impact on contract execution
-
-### How much additional gas do Builder Codes cost?
-
-The ERC-8021 suffix adds a negligible amount of gas to each transaction at 16 gas per non-zero byte.
-
-### Will Builder Codes expose my identity?
-
-**No.** Builder Codes only associate transactions with your application—they don't expose any wallet information that isn't already public onchain.
-
-### Can I use ERC-8021 with Externally Owned Accounts (EOAs)?
-
-**Yes.** ERC-8021 works with both EOAs and smart contract wallets.
-
-### How do I verify that my transaction was properly attributed?
-
-**1. Check base.dev**
-
-- Visit [base.dev](https://base.dev)
-- Select **Onchain** from the transaction type dropdown
-- Under the Total Transactions section, attribution counts increment when transactions with your code are processed
-
-**2. Use a Block Explorer (Basescan, Etherscan, etc.)**
-
-- Find your transaction hash
-- View the input data field
-- Verify the last 16 bytes are the `8021` repeating.
-- Decode the suffix to confirm your Builder Code is present
-
-**3. Open Source Tools**
-
-- Use the [Builder Code Validation](https://builder-code-checker.vercel.app/) tool
-- Select transaction type
-- Enter the transaction or UserOperation hash
-- Click the **Check Attribution** button
-
-
-### What wallets and SDKs currently support ERC-8021?
-
-**EOAs:**
-
-All EOA wallets support `dataSuffix` by default.
-
-**SDKs:**
-
-- **viem/wagmi** - TypeScript SDK with native `dataSuffix` parameter support for server-side and client-side transactions
-
-
-This requires `viem@2.45.0` or higher
-
-
-**Embedded Wallets:**
-
-- **Privy** - Embedded wallet solution with ERC-8021 capability
-- **Turnkey** - Infrastructure for programmatic wallets
-
-**Smart Wallets:**
-
-Wallets supporting ERC-5792 can use the `DataSuffixCapability` for clean suffix appending:
-
-```javascript
-await wallet.sendCalls({
- calls: [...],
- capabilities: {
- dataSuffix: {
- value: "0x07626173656170700080218021802180218021802180218021"
- optional: true
- }
- }
-});
-```
-
-## Additional Resources
-
-- [Official ERC-8021 Proposal ](https://eip.tools/eip/8021)
-- [Builder Code Docs](/base-chain/builder-codes/builder-codes)
-- [Builder Code Validation tool](https://builder-code-checker.vercel.app/)
diff --git a/docs/base-chain/builder-codes/builder-codes.mdx b/docs/base-chain/builder-codes/builder-codes.mdx
index 35a0e3358..4373a0284 100644
--- a/docs/base-chain/builder-codes/builder-codes.mdx
+++ b/docs/base-chain/builder-codes/builder-codes.mdx
@@ -1,473 +1,121 @@
---
title: "Base Builder Codes"
-description: "Integrate Builder Codes to attribute onchain activity to your app or wallet."
+description: "Attribute onchain activity to your app or wallet with Builder Codes."
---
-## What are Builder Codes
+## What Are Builder Codes
Base Builder Codes are an ERC-721 NFT collection where unique codes (e.g. "abc123") are minted to help identify builders onchain.
Each code has associated metadata. Onchain metadata primarily includes a "payout address" where each code declares where potential rewards should be sent to. Offchain metadata includes more details about the app including its name and site.
-## Automatic Builder-Code Attribution on Base
+
+ Get your Builder Code by registering on [base.dev](https://base.dev/). You can find your code under **Settings** → **Builder Code**.
+
-Once your app is registered on [Base.dev](http://base.dev/), the Base App will auto-append your Base Builder Code to transactions its users make in your app (e.g. via your mini app, or the Base App's browser). This powers your onchain analytics in [Base.dev](http://base.dev/) and qualifies you for potential future rewards.
+## Integration Guides
-## For App Developers
+
+
+ Integrate Builder Codes using Wagmi or Viem
+
+
+ Implement the dataSuffix capability
+
+
+ Integrate with the Base-Solana bridge
+
+
-When you register on [base.dev](https://base.dev/), you will receive a **Builder Code**—a random string (e.g., `bc_b7k3p9da`) that you'll use to generate your attribution suffix.
+## Benefits
-
- You can find your code anytime under **Settings** → **Builder Code**.
-
+- **Rewards:** If your app drives transactions, Builder Codes let Base automatically attribute that usage back to you, unlocking rewards as the program expands.
+- **Analytics:** Reliably track onchain usage, user acquisition, and conversion metrics in Base.dev.
+- **Visibility:** Apps with Builder Codes can show up in discovery surfaces like App Leaderboards, Base App store, and ecosystem spotlights.
-The recommended approach is to configure `dataSuffix` at the client level, which automatically appends your Builder Code to all transactions.
+## FAQ
-
- Requires [viem](https://viem.sh) version 2.45.0 or higher, or [wagmi](https://wagmi.sh) version 2.17.0 or higher.
-
+### Do I Need to Modify My Smart Contracts?
-### Quick Setup with Wagmi
-
-
-
- Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
-
- ```bash
- npm i ox wagmi viem
- ```
-
-
-
- Add the `dataSuffix` option to your Wagmi config. This automatically appends your Builder Code to all transactions.
-
- ```ts config.ts
- import { createConfig, http } from "wagmi";
- import { base } from "wagmi/chains";
- import { Attribution } from "ox/erc8021";
-
- // Get your Builder Code from base.dev > Settings > Builder Codes
- const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"],
- });
-
- export const config = createConfig({
- chains: [base],
- transports: {
- [base.id]: http(),
- },
- dataSuffix: DATA_SUFFIX,
- });
- ```
-
-
-
- With the config in place, all transactions automatically include your Builder Code—no changes to your hooks or components. This works with both `useSendTransaction` and `useSendCalls`.
-
- ```tsx App.tsx
- import { useSendTransaction } from "wagmi";
- import { parseEther } from "viem";
-
- function SendButton() {
- const { sendTransaction } = useSendTransaction();
-
- return (
-
- );
- }
- ```
-
-
-
-### Quick Setup with Viem
-
-
-
- Install the required packages. The `dataSuffix` feature requires viem version 2.45.0 or higher.
-
- ```bash
- npm i ox viem
- ```
-
-
-
- Add the `dataSuffix` option when creating your wallet client. See the [viem wallet client docs](https://viem.sh/docs/clients/wallet) for more configuration options.
-
- ```ts client.ts
- import { createWalletClient, http } from "viem";
- import { base } from "viem/chains";
- import { Attribution } from "ox/erc8021";
-
- // Get your Builder Code from base.dev > Settings > Builder Codes
- const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"],
- });
-
- export const walletClient = createWalletClient({
- chain: base,
- transport: http(),
- dataSuffix: DATA_SUFFIX,
- });
- ```
-
-
-
- All transactions sent through this client automatically include your Builder Code.
-
- ```ts
- import { parseEther } from "viem";
- import { walletClient } from "./client";
-
- const hash = await walletClient.sendTransaction({
- to: "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
- value: parseEther("0.01"),
- });
- ```
-
-
-
-### Legacy: Per-Transaction Approach
-
-
- If you need to append the suffix on a per-transaction basis rather than at the client level, you can pass `dataSuffix` directly to the transaction.
-
-
-
- ```tsx App.tsx
- import { useSendTransaction } from "wagmi";
- import { parseEther } from "viem";
- import { Attribution } from "ox/erc8021";
-
- const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"],
- });
-
- function App() {
- const { sendTransaction } = useSendTransaction();
-
- return (
-
- );
- }
- ```
-
-
- When using `useSendCalls`, pass the suffix via the `capabilities` object. This requires the connected wallet to support the `dataSuffix` capability.
-
- ```tsx App.tsx
- import { useSendCalls } from "wagmi";
- import { parseEther } from "viem";
- import { Attribution } from "ox/erc8021";
-
- const DATA_SUFFIX = Attribution.toDataSuffix({
- codes: ["YOUR-BUILDER-CODE"],
- });
-
- function App() {
- const { sendCalls } = useSendCalls();
-
- return (
-
- );
- }
- ```
-
-
-
+**No.** The attribution suffix is appended to the end of transaction calldata. Smart contracts execute normally and ignore the extra data. Attribution is extracted by offchain indexers after the fact.
-### Verify Attribution
+This means:
-To confirm your Builder Code is being appended correctly, see [How do I verify that my transaction was properly attributed?](/base-chain/builder-codes/builder-codes-faq#how-do-i-verify-that-my-transaction-was-properly-attributed) in the FAQ.
+- Any existing smart contract automatically supports ERC-8021
+- No upgrades or redeployments required
+- Zero impact on contract execution
-## For Wallet Developers
+### How Much Additional Gas Do Builder Codes Cost?
-Wallet providers need to support the `dataSuffix` capability to enable attribution. This involves accepting the capability and appending the suffix to the calldata before signing.
+The ERC-8021 suffix adds a negligible amount of gas to each transaction at 16 gas per non-zero byte.
-
-
- Your wallet should accept a `dataSuffix` object in the `capabilities` object of `wallet_sendCalls`.
+### Will Builder Codes Expose My Identity?
- ```typescript
- type DataSuffixCapability = {
- value: `0x${string}`; // hex-encoded bytes provided by the app
- optional?: boolean; // whether the capability is optional
- }
- ```
-
-
-
-
- When constructing the transaction or User Operation, extract the `dataSuffix` and append it to the calldata.
-
-
-
- Append to `tx.data`.
-
- ```typescript
- // Minimal example for EOA
- function applySuffixToEOA(tx, capabilities) {
- const suffix = capabilities.dataSuffix?.value
- if (!suffix) return tx
-
- return {
- ...tx,
- // Append suffix bytes (remove 0x prefix from suffix if tx.data has it)
- data: tx.data + suffix.slice(2)
- }
- }
- ```
-
-
- Append to `userOp.callData` (not the transaction-level calldata).
-
- ```typescript
- // Minimal example for ERC-4337
- function applySuffixToUserOp(userOp, capabilities) {
- const suffix = capabilities.dataSuffix?.value
- if (!suffix) return userOp
-
- return {
- ...userOp,
- // Append suffix bytes to the UserOp callData
- callData: userOp.callData + suffix.slice(2)
- }
- }
- ```
-
-
-
-
-
- Wallets may also include their own attribution code (their own ERC-8021 suffix) by prepending the wallet's suffix before the app's.
-
- - **No interaction required with apps:** The wallet handles this independently.
- - **Multi-code support:** ERC-8021 natively supports multiple attribution codes.
-
- **Example:**
-
- ```typescript
- finalSuffix = walletSuffix + appSuffix
- ```
-
- This ensures both the app and the wallet receive onchain attribution.
-
-
-
-
-## For Base-Solana Bridge Developers
-
-Builder codes work with the [Base-Solana bridge](/base-chain/quickstart/base-solana-bridge) via the [`hookData`](https://github.com/base/flywheel/blob/30266bba4649b0eb161e55bfa4755651049a5d1f/src/hooks/BridgeReferralFees.sol#L75) mechanism. Currently available for **Solana → Base** flows only.
-
-
-
- When you register on base.dev, you will find a Builder Code under your app's settings. This is a random string (e.g., k3p9da) that you will use to generate your attribution suffix.
-
-
-
- ABI-encode the user address, your code, and fee:
-
- ```solidity
- bytes memory hookData = abi.encode(
- 0xUSER, // destination address on Base (NOT the Twin)
- 0xBUILDER_CODE, // your builder code in type string memory
- 100 // feeBps (100 = 1%)
- );
- ```
-
-
-
-
- Set `to = BRIDGE_CAMPAIGN_ADDRESS` and attach a call to `Flywheel.send`.
-
-
-
- For a bridge with no follow-up call:
-
- ```
- to: // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
- amount: 100
- call:
- ty: Call
- to: // 0x00000F14AD09382841DB481403D1775ADeE1179F on Base Sepolia
- value: 0
- data: abi.encodeWithSelector(
- Flywheel.send.selector,
- , // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
- ,
- hookData
- )
- ```
-
-
- To chain additional calls, use `DelegateCall` with `Multicall`:
-
- ```solidity
- Call[] memory calls = new Call[](2);
-
- // 1) Flywheel attribution (must be first)
- calls[0] = Call({
- to: , // 0x00000F14AD09382841DB481403D1775ADeE1179F on Base Sepolia
- value: 0,
- data: abi.encodeWithSelector(
- Flywheel.send.selector,
- , // 0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9 on Base Sepolia
- , // e.g. For SOL on Base Sepolia, use 0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC
- hookData
- )
- });
-
- // 2) Your follow-up call
- calls[1] = Call({
- to: ,
- value: 0,
- data: abi.encodeWithSelector(YourContract.yourFunction.selector)
- });
- ```
-
- Then set the bridge call to:
-
- ```
- call:
- ty: DelegateCall
- to: // 0xcA11bde05977b3631167028862bE2a173976CA11 on Base Mainnet
- data: abi.encodeWithSelector(Multicall.multicall.selector, calls)
- ```
-
-
-
-
-
- [Terminally Onchain](https://terminallyonchain.com/) is a production Next.js app that exposes the bridge via a command terminal UI. Users connect a Solana wallet, type commands such as to bridge and call a contract on Base:
-
- You can use [Terminally Onchain](https://terminallyonchain.com/) to test bridge transactions with Builder Codes like so:
-
- ```bash
- bridge 0.0001 sol 0xYOUR_DESTINATION_ADDRESS --with-bc YOUR_BUILDER_CODE --bc-fee YOUR_FEE_BPS
- ```
-
- To see how this is implemented, you can take a look at the [Github repo](https://github.com/base/sol2base/blob/e0c283035be1e3e345d329e2d77b05e29a1d38b3/src/components/MainContent.tsx#L667):
-
- ```typescript sol2base/MainContent.tsx expandable
- // Constants
- const BRIDGE_CAMPAIGN_ADDRESS = "0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9";
- const FLYWHEEL_ADDRESS = "0x00000F14AD09382841DB481403D1775ADeE1179F";
- const MULTICALL_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
-
- // Encode hookData: (address user, string code, uint8 feeBps)
- const buildBuilderHookData = (
- destination: string,
- builderCode: string,
- feeBps: number
- ) => {
- const coder = new AbiCoder();
- return coder.encode(
- ["address", "string", "uint8"],
- [destination, builderCode, feeBps]
- );
- };
-
- // Build Flywheel.send call
- const buildBuilderCall = (
- destination: string,
- builderCode: string,
- feeBps: number,
- tokenAddress: string
- ): BaseContractCall => {
- const hookData = buildBuilderHookData(destination, builderCode, feeBps);
- const data = encodeFunctionData({
- abi: FLYWHEEL_ABI,
- functionName: "send",
- args: [BRIDGE_CAMPAIGN_ADDRESS, tokenAddress, hookData],
- });
- return { type: "call", target: FLYWHEEL_ADDRESS, value: "0", data };
- };
-
- // Wrap builder + user calls in Multicall (for chained calls)
- const buildMulticall = (
- builder: BaseContractCall,
- userCall: BaseContractCall
- ): BaseContractCall => {
- const data = encodeFunctionData({
- abi: MULTICALL_ABI,
- functionName: "multicall",
- args: [
- [
- { target: builder.target, callData: builder.data },
- { target: userCall.target, callData: userCall.data },
- ],
- ],
- });
- return { type: "delegatecall", target: MULTICALL_ADDRESS, value: "0", data };
- };
-
- // Usage: attach builder code to bridge
- if (payload.flags.withBc) {
- const builderCall = buildBuilderCall(
- destination,
- builderCode,
- feeBps,
- remoteToken
- );
- callOption = userCall ? buildMulticall(builderCall, userCall) : builderCall;
- }
+**No.** Builder Codes only associate transactions with your application—they don't expose any wallet information that isn't already public onchain.
+
+### Can I Use ERC-8021 with Externally Owned Accounts (EOAs)?
+
+**Yes.** ERC-8021 works with both EOAs and smart contract wallets.
+
+### How Do I Verify That My Transaction Was Properly Attributed?
- // Set destination to campaign address when using builder codes
- const destinationForBridge = builderCode
- ? BRIDGE_CAMPAIGN_ADDRESS
- : payload.destination;
- ```
+**1. Check base.dev**
+
+- Visit [base.dev](https://base.dev)
+- Select **Onchain** from the transaction type dropdown
+- Under the Total Transactions section, attribution counts increment when transactions with your code are processed
+
+**2. Use a Block Explorer (Basescan, Etherscan, etc.)**
+
+- Find your transaction hash
+- View the input data field
+- Verify the last 16 bytes are the `8021` repeating
+- Decode the suffix to confirm your Builder Code is present
+
+**3. Open Source Tools**
+
+- Use the [Builder Code Validation](https://builder-code-checker.vercel.app/) tool
+- Select transaction type
+- Enter the transaction or UserOperation hash
+- Click the **Check Attribution** button
+
+### Which Wallets Currently Support ERC-8021?
+
+**EOAs:**
+
+All EOA wallets support `dataSuffix` by default.
+
+**Smart Wallets:**
+
+Wallets supporting ERC-5792 can use the `DataSuffixCapability` for clean suffix appending.
+
+
+ ```javascript
+ await wallet.sendCalls({
+ calls: [
+ // your transaction calls
+ ],
+ capabilities: {
+ dataSuffix: {
+ value: "0x07626173656170700080218021802180218021802180218021",
+ optional: true
+ }
+ }
+ });
+ ```
+
-
-
+**Embedded Wallets:**
+- **Privy** - Embedded wallet solution with ERC-8021 capability
+- **Turnkey** - Infrastructure for programmatic wallets
-## Contract Addresses
+## Additional Resources
-| Contract | Base Mainnet | Base Sepolia |
-| -------- | ------------ | ------------ |
-| `BRIDGE_CAMPAIGN_ADDRESS` | `0x539A97cc4724d5b2740DB98Bc71445448eFC1Bde` | `0xE2AD1C34382410C30d826B019A0B3700F5c4e6c9` |
-| `FLYWHEEL_ADDRESS` | `0x00000F14AD09382841DB481403D1775ADeE1179F` | `0x00000F14AD09382841DB481403D1775ADeE1179F` |
-| `MULTICALL_ADDRESS` | `0xcA11bde05977b3631167028862bE2a173976CA11` | `0xcA11bde05977b3631167028862bE2a173976CA11` |
+- [Official ERC-8021 Proposal](https://eip.tools/eip/8021)
+- [Builder Code Validation Tool](https://builder-code-checker.vercel.app/)
-## Give feedback!
+## Give Feedback!
Base is constantly working to improve the Builder Codes experience. If you
diff --git a/docs/base-chain/builder-codes/wallet-developers.mdx b/docs/base-chain/builder-codes/wallet-developers.mdx
new file mode 100644
index 000000000..4882b873b
--- /dev/null
+++ b/docs/base-chain/builder-codes/wallet-developers.mdx
@@ -0,0 +1,80 @@
+---
+title: "Builder Codes for Wallet Developers"
+sidebarTitle: "For Wallet Developers"
+description: "Implement the dataSuffix capability in your wallet to enable Builder Code attribution."
+---
+
+## Overview
+
+Wallet providers need to support the `dataSuffix` capability to enable attribution. This involves accepting the capability and appending the suffix to the calldata before signing.
+
+
+
+ Your wallet should accept a `dataSuffix` object in the `capabilities` object of `wallet_sendCalls`.
+
+ ```typescript
+ type DataSuffixCapability = {
+ value: `0x${string}`; // hex-encoded bytes provided by the app
+ optional?: boolean; // whether the capability is optional
+ }
+ ```
+
+
+
+
+ When constructing the transaction or User Operation, extract the `dataSuffix` and append it to the calldata.
+
+
+
+ Append to `tx.data`.
+
+ ```typescript
+ // Minimal example for EOA
+ function applySuffixToEOA(tx, capabilities) {
+ const suffix = capabilities.dataSuffix?.value
+ if (!suffix) return tx
+
+ return {
+ ...tx,
+ // Append suffix bytes (remove 0x prefix from suffix if tx.data has it)
+ data: tx.data + suffix.slice(2)
+ }
+ }
+ ```
+
+
+ Append to `userOp.callData` (not the transaction-level calldata).
+
+ ```typescript
+ // Minimal example for ERC-4337
+ function applySuffixToUserOp(userOp, capabilities) {
+ const suffix = capabilities.dataSuffix?.value
+ if (!suffix) return userOp
+
+ return {
+ ...userOp,
+ // Append suffix bytes to the UserOp callData
+ callData: userOp.callData + suffix.slice(2)
+ }
+ }
+ ```
+
+
+
+
+
+ Wallets may also include their own attribution code (their own ERC-8021 suffix) by prepending the wallet's suffix before the app's.
+
+ - **No interaction required with apps:** The wallet handles this independently.
+ - **Multi-code support:** ERC-8021 natively supports multiple attribution codes.
+
+ **Example:**
+
+ ```typescript
+ finalSuffix = walletSuffix + appSuffix
+ ```
+
+ This ensures both the app and the wallet receive onchain attribution.
+
+
+
diff --git a/docs/docs.json b/docs/docs.json
index 91ca5053a..8f8998bd9 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -122,7 +122,9 @@
"group": "Builder Codes",
"pages": [
"base-chain/builder-codes/builder-codes",
- "base-chain/builder-codes/builder-codes-faq"
+ "base-chain/builder-codes/app-developers",
+ "base-chain/builder-codes/wallet-developers",
+ "base-chain/builder-codes/bridge-developers"
]
},
{
@@ -1515,10 +1517,26 @@
]
},
"redirects": [
+ {
+ "source": "/base-chain/builder-codes/builder-codes-faq",
+ "destination": "/base-chain/builder-codes/builder-codes"
+ },
{
"source": "/base-chain/quickstart/builder-codes",
"destination": "/base-chain/builder-codes/builder-codes"
},
+ {
+ "source": "/base-chain/builder-codes/builder-codes-app-developers",
+ "destination": "/base-chain/builder-codes/app-developers"
+ },
+ {
+ "source": "/base-chain/builder-codes/builder-codes-wallet-developers",
+ "destination": "/base-chain/builder-codes/wallet-developers"
+ },
+ {
+ "source": "/base-chain/builder-codes/builder-codes-bridge-developers",
+ "destination": "/base-chain/builder-codes/bridge-developers"
+ },
{
"source": "/get-started/ai-prompting",
"destination": "/get-started/docs-mcp"