@x402-teller/core
v1.0.3
Published
Self-hosted x402 payment facilitator with Solana support.
Readme
@x402-teller/core
Self-hosted x402 payment facilitator with Solana support.
This package lets API sellers run their own x402 facilitator instead of relying on third-party services like Coinbase. It supports Solana networks with built-in transaction tracking and dashboard capabilities.
What this package provides:
- Payment verification and on-chain settlement
- Solana support (mainnet and devnet)
- Transaction tracking with database models (Sequelize ORM)
- Dashboard endpoints for analytics and transaction history
- Public key endpoints for wallet-based authentication
- Framework adapters for Express
Core endpoints:
GET /supported- Lists supported payment networksGET /public-keys- Returns facilitator's public keysPOST /verify- Verifies buyer's signed payment intentPOST /settle- Settles payment on-chainGET /balance- Returns USDC balance of facilitator walletGET /dashboard/transactions- Returns paginated transaction historyGET /dashboard/endpoints- Returns endpoint usage statistics
No external facilitator. No third-party dependencies. Your own infrastructure.
Installation
npm install @x402-teller/core
# or
bun add @x402-teller/corePeer Dependencies:
express(optional) - if using Express adapter@solana/web3.js- for Solana networks
Quick Start
Option 1: Using Built-in Adapters (Recommended)
With Express
import express from "express";
import { Facilitator, createExpressAdapter } from "@x402-teller/core";
const app = express();
app.use(express.json());
const facilitator = new Facilitator({
solanaPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
solanaFeePayer: process.env.SOLANA_PUBLIC_KEY!,
networks: ["solana-devnet"], // or "solana"
payWallRouteConfig: {
"/api/protected": {
price: "$0.10",
network: "solana-devnet",
config: { description: "Premium API access" },
},
},
});
// Mounts all facilitator endpoints at /facilitator
createExpressAdapter(facilitator, app, "/facilitator");
app.listen(3000, () => console.log("Facilitator running on :3000"));Option 2: Manual Setup (Any Framework)
If you're using a different framework or want more control, you can use the Facilitator methods directly:
import { Facilitator } from "@x402-teller/core";
const facilitator = new Facilitator({
solanaPrivateKey: process.env.SOLANA_PRIVATE_KEY!,
solanaFeePayer: process.env.SOLANA_PUBLIC_KEY!,
networks: ["solana-devnet"],
payWallRouteConfig: {
"/api/protected": {
price: "$0.10",
network: "solana-devnet",
config: { description: "Premium API access" },
},
},
});
// Map these methods to your routes:
// GET /supported
const supported = facilitator.listSupportedKinds();
// POST /verify
const result = await facilitator.verifyPayment(paymentPayload, paymentRequirements);
// POST /settle
const settlement = await facilitator.settlePayment(paymentPayload, paymentRequirements);
// GET /balance?network=solana-devnet
const balance = await facilitator.getBalance("solana-devnet");
// GET /dashboard/endpoints?timeframe=24h
const endpoints = await facilitator.getPaywallEndpoints("24h");Configuring Your API
Point your paymentMiddleware to use your facilitator:
paymentMiddleware(
"your_receiving_address", // Your wallet address
{
"/protected-route": {
price: "$0.10",
network: "solana-devnet",
config: { description: "Premium content" },
},
},
{
url: "http://localhost:3000/facilitator", // Your facilitator URL
}
);Now when clients hit /protected-route:
- They see the x402 payment flow
- Your facilitator verifies and settles the payment
- Settlement happens with your key on-chain
- No third-party services involved
API Reference
Constructor
new Facilitator({
solanaPrivateKey: string; // Base58-encoded private key
solanaFeePayer: string; // Base58-encoded public key
networks: SolanaNetwork[]; // e.g., ["solana-devnet", "solana"]
payWallRouteConfig: RoutesConfig; // Route configuration for paywall endpoints
minConfirmations?: number; // Optional (default: 1)
})Methods
listSupportedKinds()
Returns the list of supported payment networks and kinds.
Returns: { kinds: Array<{ x402Version: 1; scheme: "exact"; network: string }> }
Used for: GET /supported
verifyPayment(paymentPayload, paymentRequirements)
Verifies that a buyer's signed payment intent is valid without executing the settlement.
Parameters:
paymentPayload- The payment data from the buyerpaymentRequirements- The expected payment requirements
Returns: Promise<{ valid: boolean }>
Used for: POST /verify
settlePayment(paymentPayload, paymentRequirements)
Executes the payment settlement on-chain using your private key.
Parameters:
paymentPayload- The payment data from the buyerpaymentRequirements- The expected payment requirements
Returns: Promise<{ settled: boolean; txHash?: string }>
Used for: POST /settle
getBalance(network)
Returns the USDC balance of the facilitator wallet on the specified network.
Parameters:
network- The network to check balance on (e.g., "solana-devnet", "solana")
Returns: Promise<{ balance: string; network: string }>
Used for: GET /balance?network=solana-devnet
getPaywallEndpoints(timeframe?)
Returns statistics and analytics for all configured paywall endpoints.
Parameters:
timeframe(optional) - Time period for filtering (e.g., "24h", "7d", "30d", "all")
Returns: Promise<{ endpoints: Array<EndpointStats> }>
Used for: GET /dashboard/endpoints?timeframe=24h
Transaction Tracking
The facilitator automatically tracks all payment transactions in a database using Sequelize ORM. Transaction records include:
- Payment ID and timestamp
- Network and amount
- Buyer and seller addresses
- Transaction hash
- Status (pending, verified, settled, failed)
- Error messages (if any)
Database Configuration:
By default, the facilitator uses SQLite and stores data in ./x402-teller.db. You can customize this via environment variables:
# Use a custom SQLite file location
DB_STORAGE=/path/to/database.db
# Use in-memory database (for testing)
DB_STORAGE=:memory:
# Enable SQL query logging
DB_LOGGING=trueFramework Adapters
Built-in adapters automatically mount all facilitator endpoints.
Express Adapter
import { createExpressAdapter } from "@x402-teller/core";
createExpressAdapter(facilitator, app, "/facilitator");Mounted endpoints:
GET /facilitator/supported- List supported payment networksGET /facilitator/public-keys- Get facilitator public keysPOST /facilitator/verify- Verify payment authorizationPOST /facilitator/settle- Settle payment on-chainGET /facilitator/balance- Get USDC balanceGET /facilitator/dashboard/transactions- Get transaction historyGET /facilitator/dashboard/endpoints- Get endpoint statistics
Custom Framework
For other frameworks, use the Facilitator methods directly and map them to your routes. See the "Manual Setup" section above.
Security Considerations
Hot Wallet Warning
- Your Solana private key is a hot wallet
- This key pays gas fees and executes on-chain settlements
- It has direct access to pull authorized funds from buyers
- Never commit private keys to version control
- Store them securely using environment variables or KMS
Best Practices
- Use separate wallets for facilitator operations vs. long-term storage
- Monitor transaction activity regularly via the dashboard endpoints
- Set up alerts for unusual transaction patterns
- Keep the facilitator wallet funded with just enough for gas fees
- Regularly rotate keys if possible
- Use testnet (devnet) for development and testing
- Implement rate limiting on your facilitator endpoints
- Use HTTPS in production
Examples
Full working examples are available in the monorepo:
- Express + Solana - Complete Solana devnet implementation
The example includes:
- Environment configuration
- Facilitator setup with paywall routes
- Protected routes with x402 payment requirements
- Automatic transaction tracking
What's Included
- ✅ Solana support (mainnet and devnet)
- ✅ Payment verification and settlement
- ✅ Automatic transaction tracking with SQLite
- ✅ Balance checking for facilitator wallet
- ✅ Endpoint usage analytics
- ✅ Public key endpoints for wallet authentication
- ✅ Express adapter for easy integration
- ✅ TypeScript support with full type definitions
What's Not Included
- ❌ Entitlement management (tracking who paid for what) - implement this in your application layer
- ❌ Subscription or recurring payment logic
- ❌ Refund functionality
- ❌ Multi-signature wallet support
- ❌ Frontend dashboard UI (use
create-x402-dashboardCLI to scaffold the UI)
Contributing
This package is part of the x402-Teller monorepo. Contributions are welcome!
License
See LICENSE for details.
Part of x402-Teller - Self-sovereign payment infrastructure for the open web.
