extensions/buildercode
import "github.com/x402-foundation/x402/go/v2/extensions/buildercode"
Package buildercode provides types and helpers for the Builder Code Extension (ERC-8021).
The extension enables attribution tracking for x402 payments by appending ERC-8021 Schema 2 builder codes to settlement transaction calldata. Three parties attach their builder code, each with its own dedicated, non-overlapping reservation in "s" so that no party can crowd out another's entries:
- Server: declares "a" (app), and optionally up to MAX_SERVER_SERVICE_CODES of its own "s" (service) code(s), in the 402 response via DeclareBuilderCodeExtension.
- Client: adds up to MAX_CLIENT_SERVICE_CODES of "s" (service) via NewBuilderCodeClientExtension; when the server also declared "s", the core client merges both (client first).
- Facilitator: optionally adds "w" (wallet) at settlement via BuilderCodeFacilitatorExtension, and may append its own "s" entry (up to MAX_FACILITATOR_SERVICE_CODES) via BuilderCodeFacilitatorExtension.ServiceCode.
Constants
Source: extensions/buildercode/types.go:37
const (
// MAX_CLIENT_SERVICE_CODES is the maximum client-provided service codes
// reserved in the `s` array. Enforced by NewBuilderCodeClientExtension
// independently of the server's reservation so one side can never crowd out
// the other.
MAX_CLIENT_SERVICE_CODES = 5
// MAX_SERVER_SERVICE_CODES is the maximum server-declared service codes
// reserved in the `s` array. Enforced by DeclareBuilderCodeExtension
// independently of the client's reservation so one side can never crowd out
// the other.
MAX_SERVER_SERVICE_CODES = 5
// MAX_FACILITATOR_SERVICE_CODES is the maximum facilitator-appended service
// codes reserved in the `s` array. Enforced by BuilderCodeFacilitatorExtension
// for its own ServiceCode field.
MAX_FACILITATOR_SERVICE_CODES = 1
// MAX_SERVICE_CODES is the maximum number of service codes (`s`) encoded
// onchain at settlement - the sum of each side's dedicated reservation
// (MAX_CLIENT_SERVICE_CODES, MAX_SERVER_SERVICE_CODES, MAX_FACILITATOR_SERVICE_CODES).
MAX_SERVICE_CODES = MAX_CLIENT_SERVICE_CODES + MAX_SERVER_SERVICE_CODES + MAX_FACILITATOR_SERVICE_CODES
)BUILDER_CODE is the extension identifier.
Source: extensions/buildercode/types.go:20
const BUILDER_CODE = "builder-code"ERC_8021_MARKER is the 16-byte (hex) marker appended at the end of every suffix.
Source: extensions/buildercode/types.go:23
const ERC_8021_MARKER = "80218021802180218021802180218021"SCHEMA_2_ID is the ERC-8021 Schema 2 identifier byte.
Source: extensions/buildercode/types.go:26
const SCHEMA_2_ID = 0x02Variables
BUILDER_CODE_PATTERN matches valid builder codes: 1-32 lowercase alphanumeric characters and underscores.
Source: extensions/buildercode/types.go:30
var BUILDER_CODE_PATTERN = regexp.MustCompile(`^[a-z0-9_]{1,32}$`)BUILDER_CODE_SCHEMA is the JSON Schema advertised alongside the app code in PaymentRequired.extensions.
Source: extensions/buildercode/server.go:7
var BUILDER_CODE_SCHEMA = map[string]interface{}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": map[string]interface{}{
"a": map[string]interface{}{
"type": "string",
"pattern": "^[a-z0-9_]{1,32}$",
"description": "App builder code",
},
"w": map[string]interface{}{
"type": "string",
"pattern": "^[a-z0-9_]{1,32}$",
"description": "Wallet builder code",
},
"s": map[string]interface{}{
"type": "array",
"maxItems": MAX_SERVICE_CODES,
"items": map[string]interface{}{
"type": "string",
"pattern": "^[a-z0-9_]{1,32}$",
},
"description": "Service builder codes",
},
},
"additionalProperties": false,
}Functions
func DeclareBuilderCodeExtension(appCode string, serviceCodes ...string) map[string]interface{}
Source: extensions/buildercode/server.go:42
DeclareBuilderCodeExtension declares the builder-code extension for inclusion in PaymentRequired.extensions, advertising the service's app code and, optionally, up to MAX_SERVER_SERVICE_CODES service code(s) (e.g. attribution for a server-side SDK the service depends on). Client-provided service codes are merged with these by the core client, client entries first.
It panics when appCode or any serviceCode is not a valid builder code (1-32 lowercase alphanumeric and underscore characters)
func EncodeBuilderCodeSuffix(data BuilderCodeExtensionData) ([]byte, error)
Source: extensions/buildercode/cbor.go:113
EncodeBuilderCodeSuffix builds a complete ERC-8021 Schema 2 data suffix from builder code data. The returned bytes are ready to append to settlement calldata. Format: [cbor_data][suffix_data_length (2 bytes)][schema_id (1 byte)][marker (16 bytes)].
func NewBuilderCodeClientExtension(serviceCodes ...string) *BuilderCodeClientExtension
Source: extensions/buildercode/client.go:24
NewBuilderCodeClientExtension creates a client extension that attaches the given service code(s) to payments. It accepts one or more codes so layered clients (e.g. an MCP middleware) can attribute multiple participants.
It panics when any serviceCode is not a valid builder code (1-32 lowercase alphanumeric and underscore characters) or when more than MAX_CLIENT_SERVICE_CODES are provided.
func ParseBuilderCodeSuffixFromCalldata(calldata string) (*BuilderCodeExtensionData, bool)
Source: extensions/buildercode/cbor.go:136
ParseBuilderCodeSuffixFromCalldata parses ERC-8021 Schema 2 builder code attribution from settlement calldata (hex, with or without a 0x prefix). The second return value reports whether a valid suffix was found.
Types
type BuilderCodeClientExtension
Source: extensions/buildercode/client.go:13
BuilderCodeClientExtension adds builder-code attribution to payment payloads
by attaching the client's service code(s) (s). The core client merge
preserves the server-declared app code (a) and schema after enrichment.
type BuilderCodeClientExtension struct {
// contains filtered or unexported fields
}func EnrichPaymentPayload( _ context.Context, payload types.PaymentPayload, _ types.PaymentRequired, ) (types.PaymentPayload, error)
Source: extensions/buildercode/client.go:43
EnrichPaymentPayload attaches this client's service code(s) (s). Core
extension merging re-applies the server's advertised a/schema afterwards.
func Key() string
Source: extensions/buildercode/client.go:37
Key returns the builder-code extension identifier.
type BuilderCodeExtensionData
Source: extensions/buildercode/types.go:62
BuilderCodeExtensionData holds the ERC-8021 Schema 2 fields as they appear in PaymentRequired/PaymentPayload extensions.
- A: app builder code - the x402 service that exposed the paid endpoint.
- W: wallet builder code - the facilitator that settled the payment on-chain.
- S: service builder codes - client-provided attribution codes (encoded as an array on wire).
type BuilderCodeExtensionData struct {
A string `json:"a,omitempty"`
W string `json:"w,omitempty"`
S []string `json:"s,omitempty"`
}Fields
A string`json:"a,omitempty"`W string`json:"w,omitempty"`S []string`json:"s,omitempty"`
type BuilderCodeFacilitatorExtension
Source: extensions/buildercode/facilitator.go:16
BuilderCodeFacilitatorExtension manages builder-code attribution at settlement
time. When BuilderCode is set, it is encoded as the wallet code (w); the app
code (a) and service code (s) are read from the client payment payload
extensions. When ServiceCode is set, it is appended to s within the
facilitator's own MAX_FACILITATOR_SERVICE_CODES reservation. It implements
evm.BuilderCodeFacilitatorExtension so the base evm settle paths can resolve
and append the ERC-8021 calldata suffix.
type BuilderCodeFacilitatorExtension struct {
// BuilderCode is the facilitator's own wallet code (`w`), optional.
BuilderCode string
// ServiceCode is the facilitator's own service code, appended to the `s`
// field at settlement when provided, within its own
// MAX_FACILITATOR_SERVICE_CODES reservation. BuildDataSuffix returns an
// error if this is set to an invalid builder code.
ServiceCode string
}Fields
BuilderCode stringBuilderCode is the facilitator's own wallet code (
w), optional.ServiceCode stringServiceCode is the facilitator's own service code, appended to the
sfield at settlement when provided, within its own MAX_FACILITATOR_SERVICE_CODES reservation. BuildDataSuffix returns an error if this is set to an invalid builder code.
func BuildDataSuffix(ctx evm.DataSuffixContext) ([]byte, error)
Source: extensions/buildercode/facilitator.go:42
BuildDataSuffix builds the ERC-8021 Schema 2 calldata suffix for a settlement.
a and s come from the client payment payload extensions; w is the
facilitator's own code when configured. The facilitator's own s entry
(ServiceCode) is appended after the echoed client/server codes, within its
own MAX_FACILITATOR_SERVICE_CODES reservation. Returns an error when
ServiceCode is set but is not a valid builder code. Returns nil when no
attribution is present.
func Key() string
Source: extensions/buildercode/facilitator.go:31
Key returns the builder-code extension identifier.
