Getting Started
This guide will help you set up and integrate x402-go into your Go applications.
Prerequisites
- Go 1.21 or later
- An Ethereum wallet with private key (for facilitator or client)
- Familiarity with the Gin HTTP framework (for middleware usage)
- Access to blockchain RPC endpoints (for facilitator)
Installation
Import the packages you need in your Go project:
import (
// Facilitator service and client
"github.com/vorpalengineering/x402-go/facilitator"
"github.com/vorpalengineering/x402-go/facilitator/client"
// Resource server middleware
"github.com/vorpalengineering/x402-go/resource/middleware"
// Resource client (for buyers)
resourceclient "github.com/vorpalengineering/x402-go/resource/client"
// Shared types
"github.com/vorpalengineering/x402-go/types"
)
Running the Facilitator Service
The facilitator service processes payment verification and settlement requests.
1. Set Environment Variables
The facilitator requires a private key for signing and executing on-chain transactions:
export X402_FACILITATOR_PRIVATE_KEY=0x1234567890abcdef...
Security Note: Never commit your private key to version control. Use environment variables or a secure secret manager.
2. Create Configuration
Copy the example configuration:
cp facilitator/config.example.yaml facilitator/config.yaml
Edit facilitator/config.yaml:
server:
host: "0.0.0.0"
port: 4020
# Networks use CAIP-2 identifiers (namespace:reference)
networks:
eip155:8453:
rpc_url: "https://mainnet.base.org"
eip155:84532:
rpc_url: "https://sepolia.base.org"
# Supported scheme-network combinations
supported:
- scheme: "exact"
network: "eip155:8453"
- scheme: "exact"
network: "eip155:84532"
transaction:
timeout_seconds: 120
max_gas_price: "100000000000" # 100 gwei in wei
log:
level: "info" # debug, info, warn, error
3. Start the Service
# Uses facilitator/config.yaml by default
go run ./cmd/facilitator
# Or specify a custom config path
go run ./cmd/facilitator --config=path/to/config.yaml
The facilitator starts on the configured port (default: 4020) and exposes:
| Endpoint | Method | Description |
|---|---|---|
/supported | GET | List supported payment schemes and networks |
/verify | POST | Verify a payment payload |
/settle | POST | Settle a payment on-chain |
Protecting APIs with Middleware
Add payment requirements to your Gin routes using the resource middleware:
package main
import (
"github.com/gin-gonic/gin"
"github.com/vorpalengineering/x402-go/resource/middleware"
"github.com/vorpalengineering/x402-go/types"
)
func main() {
router := gin.Default()
// Configure x402 middleware
x402 := middleware.NewX402Middleware(&middleware.MiddlewareConfig{
FacilitatorURL: "http://localhost:4020",
DefaultRequirements: types.PaymentRequirements{
Scheme: "exact",
Network: "eip155:8453",
Amount: "1000000", // 1 USDC (6 decimals)
PayTo: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
},
ProtectedPaths: []string{"/api/*"},
RouteResources: map[string]*types.ResourceInfo{
"/api/data": {
Description: "Protected data endpoint",
MimeType: "application/json",
},
},
MaxBufferSize: 5 * 1024 * 1024, // 5 MB max response
DiscoveryEnabled: true,
BaseURL: "https://api.example.com",
DiscoverableEndpoints: []string{"/api/data"},
})
// Apply middleware globally
router.Use(x402.Handler())
// Your routes
router.GET("/api/data", func(c *gin.Context) {
c.JSON(200, gin.H{"data": "protected content"})
})
router.Run(":3000")
}
The middleware implements the full x402 payment flow:
- Returns
402withPAYMENT-REQUIREDheader when no payment is provided - Verifies payment with the facilitator
- Executes the handler if payment is valid (response is buffered)
- Settles payment on-chain after successful response
- Returns
PAYMENT-RESPONSEheader with settlement details
Using the Resource Client
For services that need to pay for resources, use the resource client:
package main
import (
"fmt"
"io"
"log"
"github.com/ethereum/go-ethereum/crypto"
"github.com/vorpalengineering/x402-go/resource/client"
)
func main() {
// Load your private key
privateKey, err := crypto.HexToECDSA("your_private_key_hex")
if err != nil {
log.Fatal(err)
}
// Create resource client
rc := client.NewResourceClient(privateKey)
url := "https://api.example.com/api/data"
// Step 1: Check if resource requires payment
resp, paymentRequired, err := rc.Check("GET", url, "", nil)
if err != nil {
log.Fatal(err)
}
// Step 2: If payment required, inspect requirements and decide to pay
if paymentRequired != nil {
selected := paymentRequired.Accepts[0]
log.Printf("Payment required: %s on %s", selected.Amount, selected.Network)
// Step 3: Pay for resource (generates EIP-3009 authorization)
resp, err = rc.Pay("GET", url, "", nil, &selected)
if err != nil {
log.Fatal(err)
}
}
// Use the response
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Response: %s\n", body)
}
Using the Facilitator Client
For direct integration with a facilitator service:
package main
import (
"fmt"
"log"
"github.com/vorpalengineering/x402-go/facilitator/client"
"github.com/vorpalengineering/x402-go/types"
)
func main() {
c := client.NewClient("http://localhost:4020")
// Get supported schemes
supported, err := c.Supported()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Supported: %+v\n", supported)
// Verify a payment
verifyResp, err := c.Verify(&types.VerifyRequest{
PaymentPayload: paymentPayload,
PaymentRequirements: types.PaymentRequirements{
Scheme: "exact",
Network: "eip155:8453",
Amount: "1000000",
PayTo: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
},
})
if err != nil {
log.Fatal(err)
}
if verifyResp.IsValid {
log.Printf("Payment valid from: %s", verifyResp.Payer)
}
// Settle a payment
settleResp, err := c.Settle(&types.SettleRequest{
PaymentPayload: paymentPayload,
PaymentRequirements: requirements,
})
if err != nil {
log.Fatal(err)
}
if settleResp.Success {
fmt.Printf("Settled: tx=%s, network=%s\n", settleResp.Transaction, settleResp.Network)
}
}
Using the CLI Tool
Build and use the CLI for testing and management:
# Build
go build ./cmd/x402cli
# Check facilitator supported schemes
./x402cli supported -u http://localhost:4020
# Check if a resource requires payment
./x402cli check -u https://api.example.com/api/data
# Browse discovery endpoint
./x402cli browse -u https://api.example.com
# Generate payment requirements
./x402cli req --scheme exact --network eip155:8453 --amount 1000000
# Generate payment payload (requires private key)
./x402cli payload --req requirements.json --private-key 0x...
# Pay for a resource
./x402cli pay -u https://api.example.com/api/data \
-p payload.json --req requirements.json
Docker
Both the facilitator and CLI can be run as containers:
# Start the facilitator service
export X402_FACILITATOR_PRIVATE_KEY=0x...
docker compose up facilitator
# Run a CLI command
docker compose run --rm x402cli supported -u http://facilitator:4020
# Build images without starting
docker compose build
The facilitator mounts facilitator/config.yaml into the container. Ensure the file exists before running:
cp facilitator/config.example.yaml facilitator/config.yaml
Next Steps
- Review the CLI Reference for complete CLI documentation
- Check the API Reference for detailed package documentation
- Read the x402 specification for protocol details