Skip to content

Configuration

Deep dive into x402test configuration options.

x402test.config.js
export default {
// Server settings
port: 4402,
network: "solana-devnet",
rpcUrl: "http://localhost:8899",
recipient: "YOUR_WALLET_ADDRESS",
// Route definitions
routes: {
"/path": {
price: "0.01",
description: "Description",
status: 200,
response: {},
},
},
};
{
port: 4402; // Default port
}

Override with CLI:

Terminal window
npx x402test start --port 8080

Or environment variable:

{
port: parseInt(process.env.PORT || "4402");
}
{
network: "solana-devnet"; // or 'solana-localnet', 'solana-mainnet'
}
{
rpcUrl: "http://localhost:8899"; // Local validator
// rpcUrl: 'https://api.devnet.solana.com' // Public devnet
// rpcUrl: 'https://api.mainnet-beta.solana.com' // Mainnet
}
{
recipient: "FcxKSp7YxqYXdq..."; // Wallet to receive payments
}
routes: {
'/api/endpoint': {
price: '0.01',
description: 'Endpoint description',
response: { data: 'static response' }
}
}
routes: {
'/api/dynamic': {
price: '0.01',
description: 'Dynamic endpoint',
response: (req) => ({
method: req.method,
path: req.path,
query: req.query,
body: req.body,
timestamp: Date.now()
})
}
}
routes: {
'/api/created': {
price: '0.01',
status: 201, // Custom status
response: { created: true }
}
}
routes: {
'/api/validated': {
price: '0.05',
response: (req) => {
// Validate request
if (!req.query.userId) {
return {
error: 'userId parameter required',
status: 400
};
}
return {
userId: req.query.userId,
data: 'Your data'
};
}
}
}
const isDev = process.env.NODE_ENV !== "production";
export default {
port: isDev ? 4402 : 8080,
network: isDev ? "solana-localnet" : "solana-devnet",
rpcUrl: isDev ? "http://localhost:8899" : "https://api.devnet.solana.com",
recipient: process.env.RECIPIENT_WALLET,
routes: isDev ? devRoutes : prodRoutes,
};
config/dev.js
export const devConfig = {
port: 4402,
network: "solana-localnet",
rpcUrl: "http://localhost:8899",
routes: {
/* dev routes */
},
};
// config/prod.js
export const prodConfig = {
port: 8080,
network: "solana-devnet",
rpcUrl: "https://api.devnet.solana.com",
routes: {
/* prod routes */
},
};
// x402test.config.js
import { devConfig } from "./config/dev.js";
import { prodConfig } from "./config/prod.js";
const env = process.env.NODE_ENV || "development";
export default env === "production" ? prodConfig : devConfig;
import { readdirSync, readFileSync } from "fs";
import { join } from "path";
function loadRoutes(dir) {
const routes = {};
const files = readdirSync(dir);
for (const file of files) {
if (file.endsWith(".json")) {
const content = readFileSync(join(dir, file), "utf8");
const route = JSON.parse(content);
routes[route.path] = route.config;
}
}
return routes;
}
export default {
port: 4402,
network: "solana-devnet",
rpcUrl: "http://localhost:8899",
recipient: process.env.RECIPIENT_WALLET,
routes: loadRoutes("./routes"),
};
function createRoute(path, price, handler) {
return {
[path]: {
price,
description: `Auto-generated route for ${path}`,
response: handler,
},
};
}
const routes = {
...createRoute("/api/users", "0.01", getUsersHandler),
...createRoute("/api/products", "0.02", getProductsHandler),
...createRoute("/api/orders", "0.05", getOrdersHandler),
};
export default {
// ... other config
routes,
};
x402test.config.ts
import type { ServerConfig, RouteConfig } from "x402test/server/config";
import type { Request } from "express";
const routes: Record<string, RouteConfig> = {
"/api/typed": {
price: "0.01",
description: "Typed endpoint",
response: (req: Request) => ({
method: req.method,
path: req.path,
}),
},
};
const config: ServerConfig = {
port: 4402,
network: "solana-devnet",
rpcUrl: "http://localhost:8899",
recipient: process.env.RECIPIENT_WALLET || "",
routes,
};
export default config;
  1. Use Environment Variables: Never hardcode sensitive data
  2. Separate Concerns: Keep routes in separate files
  3. Type Safety: Use TypeScript for configuration
  4. Validation: Validate configuration on startup
  5. Documentation: Document custom routes