Skip to content

Feat: 8021 Schema v2 support for x402#2329

Open
0xClouds wants to merge 6 commits into
x402-foundation:mainfrom
pk-coinbase:feat/builder-code-extension
Open

Feat: 8021 Schema v2 support for x402#2329
0xClouds wants to merge 6 commits into
x402-foundation:mainfrom
pk-coinbase:feat/builder-code-extension

Conversation

@0xClouds
Copy link
Copy Markdown
Contributor

Description

Adds a new builder-code extension that enables ERC-8021 Schema 2 attribution tracking for x402 payments. Two parties attach their builder code to settlement transactions:

  • Service (resource server): declares its code as the "a" (app) field in the 402 response via declareBuilderCodeExtension()
  • Facilitator: adds its code as the "w" (wallet) field at settlement via BuilderCodeFacilitatorExtension

The service can optionally include related on-chain services (e.g., Morpho, Aerodrome) in the "s" array to attribute protocols it depends on.

At settlement, the facilitator encodes all builder codes as a Schema 2 CBOR suffix and appends it to the transferWithAuthorization calldata. The EVM ignores trailing calldata bytes, so the transfer executes normally while indexers (Coindexer, Beacon, Dune) can parse the suffix.

Schema 2 Suffix

{
  a: "bc_my_service",                            // app that exposed the x402 endpoint
  w: "bc_my_facilitator",                        // wallet/facilitator that settled on-chain
  s: ["bc_morpho", "bc_aerodrome"]               // related on-chain services (optional)
}

Encoded as: [CBOR data][length 2B][schema_id 0x02][8021 marker 16B]

Flow

Client                      Service                      Facilitator
  |                            |                             |
  |-- GET /resource ---------->|                             |
  |<-- 402 + builder-code ext -|                             |
  |   a: service's code        |                             |
  |   s: [related services]    |                             |
  |                            |                             |
  |-- GET /resource + payment >|                             |
  |                            |-- /verify (/settle) ------->|
  |                            |   (passthrough, untouched)  |
  |                            |                             |
  |                            |   Reads a + s from payload  |
  |                            |   Adds own code as w        |
  |                            |   Encodes Schema 2 CBOR     |
  |                            |   Appends to calldata       |
  |                            |                             |
  |<-- 200 + resource ---------|           Settlement TX with ERC-8021 suffix

Why

x402 payments currently have no attribution mechanism. Builder codes (ERC-8021) are the standard for on-chain attribution on Base, but they work by appending a suffix to transaction calldata — which requires the transaction submitter to cooperate. In x402, the client never submits a transaction; the facilitator does. This extension bridges that gap by flowing builder codes through the x402 payment protocol and having the facilitator append them at settlement time.

Out of Scope

  • Payment splitting / revenue share
  • Platform attribution (agent platform SDK concern)
  • Non-EVM chains (SVM/Stellar/Aptos support later)
  • Custom registries (all codes use canonical BuilderCodes contract)
  • Permit2 settlement path (EIP-3009 only for now)

Tests

Verified On-Chain

Tested on Base Sepolia with a full service → facilitator flow:

Decoded CBOR from settlement calldata:

a: "bc_demo_agent"
w: "bc_demo_facilitator"
s: ["bc_demo_service"]

Checklist

  • I have formatted and linted my code
  • All new and existing tests pass
  • My commits are signed (required for merge) -- you may need to rebase if you initially pushed unsigned commits
  • I added a changelog fragment for user-facing changes (docs-only changes can skip)

Changes

New: @x402/extensions/builder-code

  • types.ts — extension key, interfaces, builder code validation; fields: a (app), w (wallet), s (services)
  • cbor.ts — hand-rolled Schema 2 CBOR encoder (no dependencies)
  • resourceServer.tsdeclareBuilderCodeExtension(appCode, serviceCodes?) for services to declare their code as "a" with optional "s" array
  • facilitator.tsBuilderCodeFacilitatorExtension with buildCalldataSuffix() that adds its code as "w"

Modified: @x402/evm (exact facilitator)

  • eip3009-utils.tsexecuteTransferWithAuthorization() accepts optional calldataSuffix; when present, uses encodeFunctionData() + sendTransaction() instead of writeContract()
  • eip3009.tssettleEIP3009() accepts FacilitatorContext, reads builder code extension, passes suffix
  • scheme.ts — passes context to settleEIP3009()

pk-coinbase and others added 5 commits April 2, 2026 17:33
…ments

Adds a new builder-code extension that enables ERC-8021 Schema 2
attribution tracking for x402 payments. Three parties can attach
their builder code to settlement transactions:

- Agent (client): sets the "a" field via BuilderCodeClientExtension
- Service (server): declares in 402 response via declareBuilderCodeExtension()
- Facilitator: adds to "s" array at settlement via BuilderCodeFacilitatorExtension

At settlement, the facilitator encodes all builder codes as a Schema 2
CBOR suffix and appends it to the transferWithAuthorization calldata.
The EVM ignores trailing calldata bytes, so the transfer executes
normally while indexers (Coindexer, Beacon, Dune) can parse the suffix.

Changes:
- New extension package: @x402/extensions/builder-code
- EVM mechanism: executeTransferWithAuthorization accepts optional calldataSuffix
- settleEIP3009 reads builder code extension from FacilitatorContext
- scheme.ts passes context through to EIP-3009 settlement
…t extension

- Service declares its builder code as "a" (app) — it's the application
  exposing the x402 endpoint
- Facilitator adds its code as "w" (wallet) — it's the entity that signs
  and broadcasts the settlement transaction
- Service can optionally include related on-chain services in "s" array
  (e.g., Morpho, Aerodrome)
- Remove BuilderCodeClientExtension — agent doesn't attach builder codes,
  the service's extension data passes through untouched
- CBOR encoder now handles "a", "w", and "s" fields
@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

@0xClouds is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot added typescript go sdk Changes to core v2 packages examples Changes to examples labels May 15, 2026
@phdargen phdargen self-assigned this May 16, 2026
@@ -0,0 +1,85 @@
package main
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples expect that you run:

  • Client
  • Facilitator
  • Server

in order to test the E2E flow. They do work in isolation but will mock data

@phdargen
Copy link
Copy Markdown
Collaborator

Hi @0xClouds @pk-coinbase, I opened a PR on top of your branch: pk-coinbase#2

This includes the following TS only changes:

  • Refactored builder-code plumbing in core package to better align with existing gas extension approach and make it easier to extend calldata suffix support to remaining schemes and assertTransferMethods
  • Added new client extension to support client provided 's' builder code
  • Implemented facilitator verification of builder code formatting and payload vs requirements consistency
  • Added calldata suffix support to exact permit2, upto and batch-settlement
  • Added examples
  • Added unit/integration tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

examples Changes to examples go sdk Changes to core v2 packages typescript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants