Extensions

extensions/buildercode

Package buildercode provides types and helpers for the Builder Code Extension (ERC-8021).

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 = 0x02

Variables

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 string

    BuilderCode is the facilitator's own wallet code (w), optional.

  • ServiceCode 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.

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.