echo

package
v0.0.0-...-0e07cd4 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

x402 Echo Middleware

Echo middleware integration for the x402 Payment Protocol. This package provides middleware for adding x402 payment requirements to your Echo applications.

Installation

go get github.com/coinbase/x402/go

Quick Start

package main

import (
	x402http "github.com/coinbase/x402/go/http"
	echomw "github.com/coinbase/x402/go/http/echo"
	evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server"
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()

	facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
		URL: "https://facilitator.x402.org",
	})

	routes := x402http.RoutesConfig{
		"GET /protected": {
			Accepts: x402http.PaymentOptions{
				{
					Scheme:  "exact",
					PayTo:   "0xYourAddress",
					Price:   "$0.10",
					Network: "eip155:84532",
				},
			},
			Description: "Access to premium content",
		},
	}

	e.Use(echomw.PaymentMiddlewareFromConfig(routes,
		echomw.WithFacilitatorClient(facilitator),
		echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
	))

	e.GET("/protected", func(c echo.Context) error {
		return c.JSON(200, map[string]interface{}{"message": "This content is behind a paywall"})
	})

	e.Logger.Fatal(e.Start(":8080"))
}

Configuration

There are two approaches to configuring the middleware:

1. PaymentMiddlewareFromConfig (Functional Options)

Use PaymentMiddlewareFromConfig with functional options:

e.Use(echomw.PaymentMiddlewareFromConfig(routes,
	echomw.WithFacilitatorClient(facilitator),
	echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
))
2. PaymentMiddlewareFromHTTPServer (Pre-configured Server)

Use PaymentMiddlewareFromHTTPServer when you need to configure the server separately (e.g., with lifecycle hooks):

server := x402.Newx402ResourceServer(
	x402.WithFacilitatorClient(facilitator),
).
	Register("eip155:*", evm.NewExactEvmScheme()).
	OnAfterSettle(func(ctx x402.SettleResultContext) error {
		log.Printf("Payment settled: %s", ctx.Result.Transaction)
		return nil
	})

httpServer := x402http.Wrappedx402HTTPResourceServer(routes, server)

e.Use(echomw.PaymentMiddlewareFromHTTPServer(httpServer))
Middleware Options
  • WithFacilitatorClient(client) - Add a facilitator client
  • WithScheme(network, server) - Register a payment scheme
  • WithPaywallConfig(config) - Configure paywall UI
  • WithSyncFacilitatorOnStart(bool) - Sync with facilitator on startup (default: true)
  • WithTimeout(duration) - Set payment operation timeout (default: 30s)
  • WithErrorHandler(handler) - Custom error handler
  • WithSettlementHandler(handler) - Settlement callback

Route Configuration

Define which routes require payment:

routes := x402http.RoutesConfig{
	"GET /api/data": {
		Accepts: x402http.PaymentOptions{
			{
				Scheme:  "exact",
				PayTo:   "0xYourAddress",
				Price:   "$0.10",
				Network: "eip155:84532",
			},
		},
		Description: "API data access",
	},
	"POST /api/compute": {
		Accepts: x402http.PaymentOptions{
			{
				Scheme:  "exact",
				PayTo:   "0xYourAddress",
				Price:   "$1.00",
				Network: "eip155:8453",
			},
		},
		Description: "Compute operation",
	},
}

Routes support wildcards:

  • "GET /api/premium/*" - Matches all GET requests under /api/premium/
  • "* /api/data" - Matches all HTTP methods to /api/data

Paywall Configuration

Configure the paywall UI for browser requests:

paywallConfig := &x402http.PaywallConfig{
	AppName: "My API Service",
	AppLogo: "https://myapp.com/logo.svg",
	Testnet: true,
}

e.Use(echomw.PaymentMiddlewareFromConfig(routes,
	echomw.WithFacilitatorClient(facilitator),
	echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
	echomw.WithPaywallConfig(paywallConfig),
))

The paywall includes:

  • EVM wallet support (MetaMask, Coinbase Wallet, etc.)
  • Solana wallet support (Phantom, Solflare, etc.)
  • USDC balance checking and chain switching
  • Onramp integration for mainnet

Advanced Usage

Multiple Payment Schemes

Register schemes for different networks:

import (
	evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server"
	svm "github.com/coinbase/x402/go/mechanisms/svm/exact/server"
)

e.Use(echomw.PaymentMiddlewareFromConfig(routes,
	echomw.WithFacilitatorClient(facilitator),
	echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
	echomw.WithScheme("solana:*", svm.NewExactSvmScheme()),
))
Custom Facilitator Client

Configure with custom authentication:

facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
	URL: "https://your-facilitator.com",
	CreateAuthHeaders: func() (*x402http.FacilitatorAuthHeaders, error) {
		return &x402http.FacilitatorAuthHeaders{
			Verify: map[string]string{"Authorization": "Bearer verify-token"},
			Settle: map[string]string{"Authorization": "Bearer settle-token"},
		}, nil
	},
})
Settlement Handler

Track successful payments:

e.Use(echomw.PaymentMiddlewareFromConfig(routes,
	echomw.WithFacilitatorClient(facilitator),
	echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
	echomw.WithSettlementHandler(func(c echo.Context, settlement *x402.SettleResponse) {
		log.Printf("Payment settled - Payer: %s, Tx: %s",
			settlement.Payer,
			settlement.Transaction,
		)
		c.Response().Header().Set("X-Payment-Receipt", settlement.Transaction)
	}),
))
Settlement Overrides (Upto Scheme)

For the upto scheme, route handlers specify the actual settlement amount via SetSettlementOverrides:

e.GET("/api/metered", func(c echo.Context) error {
	usage := calculateUsage(c)
	echomw.SetSettlementOverrides(c, &x402.SettlementOverrides{Amount: usage})

	return c.JSON(http.StatusOK, map[string]interface{}{"result": "ok"})
})
Error Handler

Custom error handling:

e.Use(echomw.PaymentMiddlewareFromConfig(routes,
	echomw.WithFacilitatorClient(facilitator),
	echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
	echomw.WithErrorHandler(func(c echo.Context, err error) {
		log.Printf("Payment error: %v", err)
		c.JSON(http.StatusPaymentRequired, map[string]interface{}{
			"error": err.Error(),
		})
	}),
))

Convenience Functions

X402Payment (Config Struct)

With struct-based configuration:

e.Use(echomw.X402Payment(echomw.Config{
	Routes:      routes,
	Facilitator: facilitator,
	Schemes:     []echomw.SchemeConfig{{Network: "eip155:*", Server: evm.NewExactEvmScheme()}},
	Timeout:     30 * time.Second,
}))
SimpleX402Payment

Apply payment requirements to all routes:

e.Use(echomw.SimpleX402Payment(
	"0xYourAddress",
	"$0.10",
	"eip155:84532",
	"https://facilitator.x402.org",
))

Complete Example

package main

import (
	"log"
	"net/http"
	"time"

	x402 "github.com/coinbase/x402/go"
	x402http "github.com/coinbase/x402/go/http"
	echomw "github.com/coinbase/x402/go/http/echo"
	evm "github.com/coinbase/x402/go/mechanisms/evm/exact/server"
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()

	facilitator := x402http.NewHTTPFacilitatorClient(&x402http.FacilitatorConfig{
		URL: "https://facilitator.x402.org",
	})

	routes := x402http.RoutesConfig{
		"GET /api/data": {
			Accepts: x402http.PaymentOptions{
				{
					Scheme:  "exact",
					PayTo:   "0xYourAddress",
					Price:   "$0.10",
					Network: "eip155:84532",
				},
			},
			Description: "Basic data access",
		},
		"POST /api/compute": {
			Accepts: x402http.PaymentOptions{
				{
					Scheme:  "exact",
					PayTo:   "0xYourAddress",
					Price:   "$1.00",
					Network: "eip155:8453",
				},
			},
			Description: "Compute operation",
		},
	}

	paywallConfig := &x402http.PaywallConfig{
		AppName: "My API Service",
		AppLogo: "/logo.svg",
		Testnet: true,
	}

	e.Use(echomw.PaymentMiddlewareFromConfig(routes,
		echomw.WithFacilitatorClient(facilitator),
		echomw.WithScheme("eip155:*", evm.NewExactEvmScheme()),
		echomw.WithPaywallConfig(paywallConfig),
		echomw.WithTimeout(60*time.Second),
		echomw.WithSettlementHandler(func(c echo.Context, settlement *x402.SettleResponse) {
			log.Printf("Payment settled: %s", settlement.Transaction)
		}),
	))

	e.GET("/api/data", func(c echo.Context) error {
		return c.JSON(http.StatusOK, map[string]interface{}{"data": "Protected content"})
	})

	e.POST("/api/compute", func(c echo.Context) error {
		return c.JSON(http.StatusOK, map[string]interface{}{"result": "Computation complete"})
	})

	e.GET("/", func(c echo.Context) error {
		return c.JSON(http.StatusOK, map[string]interface{}{"message": "Welcome"})
	})

	e.Logger.Fatal(e.Start(":8080"))
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PaymentMiddleware

func PaymentMiddleware(routes x402http.RoutesConfig, server *x402.X402ResourceServer, opts ...MiddlewareOption) echo.MiddlewareFunc

PaymentMiddleware creates Echo middleware for x402 payment handling using a pre-configured server.

func PaymentMiddlewareFromConfig

func PaymentMiddlewareFromConfig(routes x402http.RoutesConfig, opts ...MiddlewareOption) echo.MiddlewareFunc

PaymentMiddlewareFromConfig creates Echo middleware for x402 payment handling. This creates the server internally from the provided options.

func PaymentMiddlewareFromHTTPServer

func PaymentMiddlewareFromHTTPServer(httpServer *x402http.HTTPServer, opts ...MiddlewareOption) echo.MiddlewareFunc

PaymentMiddlewareFromHTTPServer creates Echo middleware using a pre-configured HTTPServer. This allows registering hooks (e.g., OnProtectedRequest) on the server before attaching to the router.

Example:

resourceServer := x402.Newx402ResourceServer(
    x402.WithFacilitatorClient(facilitator),
).Register("eip155:*", evm.NewExactEvmScheme())

httpServer := x402http.Wrappedx402HTTPResourceServer(routes, resourceServer).
    OnProtectedRequest(requestHook)

e.Use(echomw.PaymentMiddlewareFromHTTPServer(httpServer))

func SetSettlementOverrides

func SetSettlementOverrides(c echo.Context, overrides *x402.SettlementOverrides)

SetSettlementOverrides sets settlement overrides on the Echo response for partial settlement. The middleware extracts these before settlement and strips the header from the client response.

func SimpleX402Payment

func SimpleX402Payment(payTo string, price string, network x402.Network, facilitatorURL string) echo.MiddlewareFunc

SimpleX402Payment creates middleware with minimal configuration. Uses a single route pattern and facilitator for the simplest possible setup.

Args:

payTo: Payment recipient address
price: Payment amount (e.g., "$0.001")
network: Payment network
facilitatorURL: Facilitator server URL

Returns:

Echo middleware function

Example:

e.Use(echomw.SimpleX402Payment(
    "0x123...",
    "$0.001",
    "eip155:8453",
    "https://facilitator.example.com",
))

func X402Payment

func X402Payment(config Config) echo.MiddlewareFunc

X402Payment creates payment middleware using struct-based configuration. This is a cleaner, more readable alternative to PaymentMiddlewareFromConfig with variadic options.

Example:

e.Use(echomw.X402Payment(echomw.Config{
    Routes: routes,
    Facilitator: facilitatorClient,
    Schemes: []echomw.SchemeConfig{
        {Network: "eip155:*", Server: evm.NewExactEvmServer()},
        {Network: "solana:*", Server: svm.NewExactSvmServer()},
    },
    SyncFacilitatorOnStart: true,
    Timeout: 30 * time.Second,
}))

Types

type Config

type Config struct {
	// Routes maps HTTP patterns to payment requirements
	Routes x402http.RoutesConfig

	// Facilitator is a single facilitator client (most common case)
	// Use this OR Facilitators (not both)
	Facilitator x402.FacilitatorClient

	// Facilitators is an array of facilitator clients (for fallback/redundancy)
	// Use this OR Facilitator (not both)
	Facilitators []x402.FacilitatorClient

	// Schemes to register with the server
	Schemes []SchemeConfig

	// PaywallConfig for browser-based payment UI (optional)
	PaywallConfig *x402http.PaywallConfig

	// SyncFacilitatorOnStart fetches supported kinds from facilitators on startup
	// Default: true
	SyncFacilitatorOnStart bool

	// Timeout for payment operations
	// Default: 30 seconds
	Timeout time.Duration

	// ErrorHandler for custom error handling (optional)
	ErrorHandler func(echo.Context, error)

	// SettlementHandler called after successful settlement (optional)
	SettlementHandler func(echo.Context, *x402.SettleResponse)
}

Config provides struct-based configuration for x402 payment middleware. This is a cleaner alternative to the variadic options pattern.

type EchoAdapter

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

EchoAdapter implements HTTPAdapter for Echo framework

func NewEchoAdapter

func NewEchoAdapter(ctx echo.Context) *EchoAdapter

NewEchoAdapter creates a new Echo adapter

func (*EchoAdapter) GetAcceptHeader

func (a *EchoAdapter) GetAcceptHeader() string

GetAcceptHeader gets the Accept header

func (*EchoAdapter) GetHeader

func (a *EchoAdapter) GetHeader(name string) string

GetHeader gets a request header

func (*EchoAdapter) GetMethod

func (a *EchoAdapter) GetMethod() string

GetMethod gets the HTTP method

func (*EchoAdapter) GetPath

func (a *EchoAdapter) GetPath() string

GetPath gets the request path

func (*EchoAdapter) GetURL

func (a *EchoAdapter) GetURL() string

GetURL gets the full request URL

func (*EchoAdapter) GetUserAgent

func (a *EchoAdapter) GetUserAgent() string

GetUserAgent gets the User-Agent header

type MiddlewareConfig

type MiddlewareConfig struct {
	// Routes configuration
	Routes x402http.RoutesConfig

	// Facilitator client(s)
	FacilitatorClients []x402.FacilitatorClient

	// Scheme registrations
	Schemes []SchemeRegistration

	// Paywall configuration
	PaywallConfig *x402http.PaywallConfig

	// Sync with facilitator on start
	SyncFacilitatorOnStart bool

	// Custom error handler
	ErrorHandler func(echo.Context, error)

	// Custom settlement handler
	SettlementHandler func(echo.Context, *x402.SettleResponse)

	// Context timeout for payment operations
	Timeout time.Duration
}

MiddlewareConfig configures the payment middleware

type MiddlewareOption

type MiddlewareOption func(*MiddlewareConfig)

MiddlewareOption configures the middleware

func WithErrorHandler

func WithErrorHandler(handler func(echo.Context, error)) MiddlewareOption

WithErrorHandler sets a custom error handler

func WithFacilitatorClient

func WithFacilitatorClient(client x402.FacilitatorClient) MiddlewareOption

WithFacilitatorClient adds a facilitator client

func WithPaywallConfig

func WithPaywallConfig(config *x402http.PaywallConfig) MiddlewareOption

WithPaywallConfig sets the paywall configuration

func WithScheme

func WithScheme(network x402.Network, schemeServer x402.SchemeNetworkServer) MiddlewareOption

WithScheme registers a scheme server

func WithSettlementHandler

func WithSettlementHandler(handler func(echo.Context, *x402.SettleResponse)) MiddlewareOption

WithSettlementHandler sets a custom settlement handler

func WithSyncFacilitatorOnStart

func WithSyncFacilitatorOnStart(sync bool) MiddlewareOption

WithSyncFacilitatorOnStart sets whether to sync with facilitator on startup

func WithTimeout

func WithTimeout(timeout time.Duration) MiddlewareOption

WithTimeout sets the context timeout for payment operations

type SchemeConfig

type SchemeConfig struct {
	Network x402.Network
	Server  x402.SchemeNetworkServer
}

SchemeConfig configures a payment scheme for a network.

type SchemeRegistration

type SchemeRegistration struct {
	Network x402.Network
	Server  x402.SchemeNetworkServer
}

SchemeRegistration registers a scheme with the server

Jump to

Keyboard shortcuts

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