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.
Once your app is registered on 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 and qualifies you for potential future rewards.
Builder Code analytics currently only support Smart Account (AA)
transactions. EOA support is coming soon. Your attribution data is preserved
and will appear once EOA support is activated.
When you register on base.dev, you will receive a Builder Code—a random string (e.g., k3p9da) that you’ll use to generate your attribution suffix.You can find your code anytime under Settings → Builder Code.
Manual appending outside of the Base app is coming soon.
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.
1
Support the dataSuffix Capability
Your wallet should accept a dataSuffix string in the capabilities object of wallet_sendCalls.
Report incorrect code
Copy
Ask AI
interface DataSuffixCapability { dataSuffix: string; // hex-encoded bytes provided by the app}
2
Append Suffix to Calldata
When constructing the transaction or User Operation, extract the dataSuffix and append it to the calldata.
EOA Transactions
ERC-4337 User Operations
Append to tx.data.
Report incorrect code
Copy
Ask AI
// Minimal example for EOAfunction applySuffixToEOA(tx, capabilities) { const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix 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).
Report incorrect code
Copy
Ask AI
// Minimal example for ERC-4337function applySuffixToUserOp(userOp, capabilities) { const suffix = capabilities.find(c => c.dataSuffix)?.dataSuffix if (!suffix) return userOp return { ...userOp, // Append suffix bytes to the UserOp callData callData: userOp.callData + suffix.slice(2) }}
3
(Optional) Add Wallet Attribution
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.
No interaction required with apps: The wallet handles this independently.
Onchain Builder codes are currently still not live on mainnet.
Builder codes work with the Base-Solana bridge via the hookData mechanism. Currently available for Solana → Base flows only.
1
Get your Builder Code
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.
2
Build hookData
ABI-encode the user address, your code, and fee:
Report incorrect code
Copy
Ask AI
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%));
3
Attach to Bridge Message
Set to = BRIDGE_CAMPAIGN_ADDRESS and attach a call to Flywheel.send.
Simple Bridge
Bridge + Follow-Up Call
For a bridge with no follow-up call:
Report incorrect code
Copy
Ask AI
to: <BRIDGE_CAMPAIGN_ADDRESS> // 0xb61A842E4361C53C3f3c376DF3758b330BD6201c on Base Sepoliaamount: 100call: ty: Call to: <FLYWHEEL_ADDRESS> // 0x00000f14ad09382841db481403d1775adee1179f on Base Sepolia value: 0 data: abi.encodeWithSelector( Flywheel.send.selector, <BRIDGE_CAMPAIGN_ADDRESS>, // 0xb61A842E4361C53C3f3c376DF3758b330BD6201c on Base Sepolia <wSOL_ADDRESS>, hookData )
To chain additional calls, use DelegateCall with Multicall:
Report incorrect code
Copy
Ask AI
Call[] memory calls = new Call[](2);// 1) Flywheel attribution (must be first)calls[0] = Call({ to: <FLYWHEEL_ADDRESS>, // 0x00000f14ad09382841db481403d1775adee1179f on Base Sepolia value: 0, data: abi.encodeWithSelector( Flywheel.send.selector, <BRIDGE_CAMPAIGN_ADDRESS>, // 0xb61A842E4361C53C3f3c376DF3758b330BD6201c on Base Sepolia <TOKEN_ADDRESS>, // e.g. For SOL on Base Sepolia, use 0xCace0c896714DaF7098FFD8CC54aFCFe0338b4BC hookData )});// 2) Your follow-up callcalls[1] = Call({ to: <YOUR_CONTRACT>, value: 0, data: abi.encodeWithSelector(YourContract.yourFunction.selector)});
Then set the bridge call to:
Report incorrect code
Copy
Ask AI
call: ty: DelegateCall to: <MULTICALL_ADDRESS> // 0xcA11bde05977b3631167028862bE2a173976CA11 on Base Mainnet data: abi.encodeWithSelector(Multicall.multicall.selector, calls)
4
Learn More: A Full Implementation Example
Terminally Onchain 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 to test bridge transactions with Builder Codes like so:
Report incorrect code
Copy
Ask AI
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: