x402

package
v1.37.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package x402 implements the x402 Payment Protocol (LP-3028) for HTTP-native crypto payments using the 402 Payment Required status code.

The protocol enables AI agents and applications to make instant on-chain payments without human intervention, using USDC (or any ERC-3009 compatible token) on EVM chains.

Flow:

  1. Client requests a resource.
  2. Server responds with 402 and an X-Payment-Request header describing the payment.
  3. Client signs an ERC-3009 transferWithAuthorization and retries with X-Payment-Authorization.
  4. Server verifies the authorization via the facilitator and serves the resource.

Index

Constants

View Source
const (
	// Version is the x402 protocol version.
	Version = "1"

	// HeaderPaymentRequest is the header sent in 402 responses with payment details.
	HeaderPaymentRequest = "X-Payment-Request"

	// HeaderPaymentAuthorization is the header sent by clients with signed payment auth.
	HeaderPaymentAuthorization = "X-Payment-Authorization"

	// HeaderPaymentReceipt is the header sent back to clients after successful payment.
	HeaderPaymentReceipt = "X-Payment-Receipt"

	// DefaultValidFor is the default payment validity window in seconds (5 minutes).
	DefaultValidFor = 300

	// DefaultNetwork is the default settlement network.
	DefaultNetwork = "lux"

	// DefaultChainID is the Lux mainnet chain ID.
	DefaultChainID = 96369

	// USDCDecimals is the number of decimals for USDC.
	USDCDecimals = 6
)
View Source
const (
	// PaymentReceiptKey is the gin context key for the payment receipt.
	PaymentReceiptKey = "x402.receipt"
)

Variables

This section is empty.

Functions

func EIP712DomainSeparator

func EIP712DomainSeparator(name, version string, chainID int64, verifyingContract string) [32]byte

EIP712DomainSeparator computes the EIP-712 domain separator hash for ERC-3009 transferWithAuthorization on a given token contract.

func Keccak256

func Keccak256(data []byte) [32]byte

Keccak256 computes the Keccak-256 hash.

func Middleware

func Middleware(cfg *PaywallConfig, facilitator *Facilitator) gin.HandlerFunc

Middleware returns a Gin middleware that enforces x402 payment for configured routes. Routes not listed in cfg.Routes pass through without payment.

Usage:

router.Use(x402.Middleware(cfg, facilitator))

func NetHTTPMiddleware

func NetHTTPMiddleware(cfg *PaywallConfig, facilitator *Facilitator) func(http.Handler) http.Handler

NetHTTPMiddleware returns a standard net/http middleware for x402 payment. For use outside Gin (e.g., chi, standard http.Handler chains).

func RecoverSigner

func RecoverSigner(digest [32]byte, sig []byte) (string, error)

RecoverSigner recovers the Ethereum address from an EIP-712 typed data digest and a 65-byte [R || S || V] signature. Used server-side to verify that the payment authorization was signed by the claimed payer address.

func USDCAmount

func USDCAmount(cents int64) string

USDCAmount converts a USD cents amount to USDC smallest unit (6 decimals). For example, 100 cents ($1.00) becomes "1000000".

func VerifySignature

func VerifySignature(digest [32]byte, sig []byte, expectedFrom string) error

VerifySignature checks that the recovered signer matches the claimed from address.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client handles x402 payment flows for HTTP clients. When a request returns HTTP 402, the client automatically constructs a payment authorization, signs it with the provided Signer, and retries the request.

func NewClient

func NewClient(cfg ClientConfig) *Client

NewClient creates a new x402-aware HTTP client.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

Do sends an HTTP request and handles x402 payment challenges. If the server responds with 402, the client signs a payment authorization and retries the request once.

func (*Client) Get

func (c *Client) Get(url string) (*http.Response, error)

Get is a convenience method for GET requests with x402 support.

type ClientConfig

type ClientConfig struct {
	// Signer signs payment authorizations.
	Signer Signer

	// MaxPayment is the maximum amount per request in token smallest units.
	// Zero or nil means no limit.
	MaxPayment *big.Int

	// HTTPClient is the underlying HTTP client. If nil, a default client is used.
	HTTPClient *http.Client

	// TokenName is the ERC-20 token name (default: "USD Coin").
	TokenName string

	// TokenVersion is the ERC-20 token version (default: "2").
	TokenVersion string
}

ClientConfig holds configuration for creating an x402 Client.

type Facilitator

type Facilitator struct {
	// contains filtered or unexported fields
}

Facilitator handles payment verification and settlement for x402 transactions. It accepts a signed ERC-3009 transferWithAuthorization, verifies the payer's signature, checks on-chain allowance/balance, and executes the transfer.

func NewFacilitator

func NewFacilitator(cfg FacilitatorConfig) *Facilitator

NewFacilitator creates a new Facilitator.

func (*Facilitator) Settle

Settle verifies and executes a payment authorization. It validates the ERC-3009 signature, checks that the authorization matches the payment request, and either settles locally via MPC or delegates to a remote facilitator service.

type FacilitatorConfig

type FacilitatorConfig struct {
	// Registry is the processor registry for executing payments.
	Registry *processor.Registry

	// RemoteURL is the URL of a remote facilitator service.
	// If set, settlement is delegated to this service.
	RemoteURL string

	// TokenName is the ERC-20 token name (default: "USD Coin").
	TokenName string

	// TokenVersion is the ERC-20 token version (default: "2").
	TokenVersion string
}

FacilitatorConfig holds configuration for creating a Facilitator.

type PaymentAuthorization

type PaymentAuthorization struct {
	From        string `json:"from"`        // Payer address
	To          string `json:"to"`          // Facilitator address
	Value       string `json:"value"`       // Amount
	ValidAfter  int64  `json:"validAfter"`  // Unix timestamp
	ValidBefore int64  `json:"validBefore"` // Unix timestamp
	Nonce       string `json:"nonce"`       // Random 32-byte nonce (hex)
	Signature   string `json:"signature"`   // EIP-712 signature (hex)
}

PaymentAuthorization is the client's signed payment, sent via X-Payment-Authorization header. Contains an ERC-3009 transferWithAuthorization.

func ParsePaymentAuthorization

func ParsePaymentAuthorization(header string) (*PaymentAuthorization, error)

ParsePaymentAuthorization parses a PaymentAuthorization from an HTTP header value.

func (*PaymentAuthorization) IsExpired

func (pa *PaymentAuthorization) IsExpired() bool

IsExpired returns true if the authorization has expired.

func (*PaymentAuthorization) IsNotYetValid

func (pa *PaymentAuthorization) IsNotYetValid() bool

IsNotYetValid returns true if the authorization is not yet valid.

func (*PaymentAuthorization) MarshalHeader

func (pa *PaymentAuthorization) MarshalHeader() string

MarshalHeader serializes a PaymentAuthorization for use in an HTTP header.

type PaymentReceipt

type PaymentReceipt struct {
	RequestHash string `json:"requestHash"`
	Payer       string `json:"payer"`
	Payee       string `json:"payee"`
	Amount      string `json:"amount"`
	TxHash      string `json:"txHash"`
	Timestamp   int64  `json:"timestamp"`
	Success     bool   `json:"success"`
}

PaymentReceipt is returned by the facilitator after successful payment settlement.

func GetReceipt

func GetReceipt(c *gin.Context) *PaymentReceipt

GetReceipt retrieves the payment receipt from the Gin context. Returns nil if no payment was processed for this request.

type PaymentRequest

type PaymentRequest struct {
	Version     string `json:"version"`
	Network     string `json:"network"`
	ChainID     int64  `json:"chainId"`
	Facilitator string `json:"facilitator"` // Facilitator contract address
	Payee       string `json:"payee"`       // Merchant/resource owner address
	Token       string `json:"token"`       // Token contract address (e.g., USDC)
	Amount      string `json:"amount"`      // Amount in token's smallest unit
	Resource    string `json:"resource"`    // The resource path being paid for
	ValidFor    int64  `json:"validFor"`    // Validity window in seconds
}

PaymentRequest is the server's payment demand, sent in the 402 response body and X-Payment-Request header. It tells the client exactly what to pay.

func NewPaymentRequest

func NewPaymentRequest(cfg *PaywallConfig, route *RouteConfig, resourcePath string) *PaymentRequest

NewPaymentRequest creates a PaymentRequest for the given route and resource path.

func ParsePaymentRequest

func ParsePaymentRequest(header string) (*PaymentRequest, error)

ParsePaymentRequest parses a PaymentRequest from an HTTP header value.

func (*PaymentRequest) MarshalHeader

func (pr *PaymentRequest) MarshalHeader() string

MarshalHeader serializes a PaymentRequest for use in an HTTP header.

type PaywallConfig

type PaywallConfig struct {
	// Facilitator is the default facilitator contract address.
	Facilitator string

	// Payee is the default payee address (merchant).
	Payee string

	// Token is the default payment token address (USDC).
	Token string

	// Network is the default network name.
	Network string

	// ChainID is the default chain ID.
	ChainID int64

	// Routes maps path patterns to their payment configuration.
	// If a path is not in this map, it passes through without payment.
	Routes map[string]*RouteConfig

	// FacilitatorURL is the URL of the facilitator service for settlement.
	FacilitatorURL string
}

PaywallConfig holds the configuration for the x402 paywall middleware.

type RouteConfig

type RouteConfig struct {
	Path        string // URL path pattern
	Payee       string // Merchant address for this route
	Token       string // Token address (default: USDC)
	Amount      string // Amount in smallest token unit
	Network     string // Network name (default: "lux")
	ChainID     int64  // Chain ID (default: 96369)
	Facilitator string // Facilitator contract address
	ValidFor    int64  // Validity window in seconds
}

RouteConfig defines x402 payment requirements for a specific route.

type Signer

type Signer interface {
	// Address returns the signer's Ethereum address.
	Address() string

	// SignDigest signs a 32-byte EIP-712 digest and returns a 65-byte
	// [R(32) || S(32) || V(1)] signature.
	SignDigest(digest [32]byte) ([]byte, error)
}

Signer signs EIP-712 typed data digests. Implementations include private key signers, hardware wallet signers, and MPC signers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL