A TypeScript library implementing the x402 Payment Protocol facilitator pattern. This library provides payment verification and settlement functionality for both EVM and SVM (Solana Virtual Machine) networks.
Hydra-Facilitator is an early-stage TypeScript project in the AI payments / x402 ecosystem. It currently has 6 GitHub stars and 0 forks.
A TypeScript library implementing the x402 Payment Protocol facilitator pattern. This library provides payment verification and settlement functionality for both EVM and SVM (Solana Virtual Machine) networks.
Version: 0.7.0 License: Apache-2.0 Repository: Hydraprotocol402/Hydra-Facilitator
The facilitator is an optional but recommended service that simplifies payment verification and settlement between clients (buyers) and servers (sellers) in the x402 protocol. Unlike traditional payment processors, the facilitator does not hold funds or act as a custodian. It performs verification and execution of onchain transactions based on signed payloads provided by clients.
pnpm add x402-hydra-facilitator
# or
npm install x402-hydra-facilitator
# or
yarn add x402-hydra-facilitator
base, base-sepoliapolygon, polygon-amoyavalanche, avalanche-fujiabstract, abstract-testnetsei, sei-testnetiotexpeaqsolana, solana-devnetimport { verify, settle } from "x402-hydra-facilitator";
import { createConnectedClient, createSigner } from "x402-hydra-facilitator/shared";
import type { PaymentPayload, PaymentRequirements } from "x402-hydra-facilitator/types";
// Verification (read-only, no private key needed)
const client = createConnectedClient("base-sepolia");
const verifyResult = await verify(
client,
paymentPayload,
paymentRequirements
);
if (verifyResult.isValid) {
console.log(`Payment valid from ${verifyResult.payer}`);
// Settlement (requires private key)
const signer = createSigner("base-sepolia", privateKey);
const settleResult = await settle(
signer,
paymentPayload,
paymentRequirements
);
if (settleResult.success) {
console.log(`Payment settled: ${settleResult.transaction}`);
}
}
verify(client, payload, requirements, config?)Verifies a payment payload against payment requirements without submitting to the blockchain.
Parameters:
client: ConnectedClient | Signer - Blockchain client (read-only for EVM, signer for SVM)payload: PaymentPayload - Signed payment payload from clientrequirements: PaymentRequirements - Server's payment requirementsconfig?: X402Config - Optional configuration (e.g., custom RPC URLs)Returns: Promise<VerifyResponse>
interface VerifyResponse {
isValid: boolean;
invalidReason?: string;
payer: string;
}
settle(signer, payload, requirements, config?)Settles a verified payment on the blockchain.
Parameters:
signer: Signer - Wallet signer with private keypayload: PaymentPayload - Signed payment payload from clientrequirements: PaymentRequirements - Server's payment requirementsconfig?: X402Config - Optional configurationReturns: Promise<SettleResponse>
interface SettleResponse {
success: boolean;
transaction?: string; // Transaction hash/signature
network: string;
payer: string;
errorReason?: string;
}
import { createConnectedClient, createSigner } from "x402-hydra-facilitator/shared";
// For verification (read-only)
const client = createConnectedClient("base-sepolia");
// For settlement (requires private key as hex string)
const signer = createSigner("base-sepolia", "0x...");
import { createSigner } from "x402-hydra-facilitator/shared";
// Both verification and settlement require a signer
// Private key must be base58 encoded string
const signer = createSigner("solana-devnet", "base58...");
// Optional: Custom RPC URL for SVM
const config = {
svmConfig: {
rpcUrl: "https://custom-rpc.example.com"
}
};
// Optional: Custom RPC URL for EVM (if using EVM networks)
const evmConfig = {
evmConfig: {
rpcUrl: "https://custom-evm-rpc.example.com"
}
};
A complete NestJS server implementation is provided in examples/nestjs/. This example includes:
/verify, /settle, and /supportedSee the NestJS example README for detailed setup instructions.
The NestJS example uses the published npm package by default. For local development:
# Set up local development (links the built package)
npm run dev:setup
# Tear down local development (uses published package)
npm run dev:teardown
Alternatively, you can manually link:
# In the main package directory
npm run build # This automatically creates npm link
# In the NestJS example directory
npm run dev:link # Links to local package
npm run dev:unlink # Uses published package
import express from "express";
import { verify, settle } from "x402-hydra-facilitator";
import { createConnectedClient, createSigner } from "x402-hydra-facilitator/shared";
import { PaymentPayloadSchema, PaymentRequirementsSchema } from "x402-hydra-facilitator/types";
const app = express();
app.use(express.json());
// POST /verify
app.post("/verify", async (req, res) => {
const payload = PaymentPayloadSchema.parse(req.body.paymentPayload);
const requirements = PaymentRequirementsSchema.parse(req.body.paymentRequirements);
const client = createConnectedClient(requirements.network);
const result = await verify(client, payload, requirements);
res.json(result);
});
// POST /settle
app.post("/settle", async (req, res) => {
const payload = PaymentPayloadSchema.parse(req.body.paymentPayload);
const requirements = PaymentRequirementsSchema.parse(req.body.paymentRequirements);
const privateKey = process.env.PRIVATE_KEY!;
const signer = createSigner(requirements.network, privateKey);
const result = await settle(signer, payload, requirements);
res.json(result);
});
app.listen(3000);
Optional configuration for customizing behavior:
interface X402Config {
evmConfig?: {
rpcUrl?: string; // Custom EVM RPC URL
};
svmConfig?: {
rpcUrl?: string; // Custom Solana RPC URL
};
}
When running a facilitator service:
EVM_PRIVATE_KEY - Private key for EVM networks (hex string)SVM_PRIVATE_KEY - Private key for Solana networks (base58 encoded)EVM_RPC_URL - Custom EVM RPC URL (optional)SVM_RPC_URL - Custom Solana RPC URL (optional)Currently supports the "exact" payment scheme:
transferWithAuthorization for USDC transfersThe architecture supports adding additional schemes. See src/schemes/ for implementation details.
src/
├── facilitator/ # Core facilitator functions
│ ├── facilitator.ts # Main verify() and settle() functions
│ └── index.ts
├── schemes/ # Payment scheme implementations
│ └── exact/
│ ├── evm/ # EVM-specific implementation
│ └── svm/ # SVM-specific implementation
├── shared/ # Shared utilities
│ ├── evm/ # EVM helpers (ERC20, USDC)
│ └── svm/ # SVM helpers (RPC, transactions, wallet)
└── types/ # TypeScript type definitions
├── config.ts # Configuration types
├── verify/ # Verification and settlement types
└── shared/ # Shared types (network, wallet, etc.)
# Install dependencies
pnpm install
# Build the project
pnpm build
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Lint code
pnpm lint
# Format code
pnpm format
The package exports multiple entry points:
x402-hydra-facilitator - Main facilitator functionsx402-hydra-facilitator/facilitator - Facilitator modulex402-hydra-facilitator/shared - Shared utilities and client creationx402-hydra-facilitator/shared/evm - EVM-specific utilitiesx402-hydra-facilitator/schemes - Payment scheme implementationsx402-hydra-facilitator/types - TypeScript type definitionscreateConnectedClient() for EVM verification (read-only) and createSigner() for settlementisValid and success flags and handle invalidReason and errorReason appropriatelysettle() function waits for blockchain confirmation before returningLicensed under the Apache License, Version 2.0. See the LICENSE file for details.
Contributions are welcome! Please see the repository for contribution guidelines.