UNPKG

ai-payments

Version:

A TypeScript library for AI payments functionality

274 lines (212 loc) 6.47 kB
# ai-payments A TypeScript library that integrates payment functionality with MCP (Model Context Protocol) servers, enabling developers to easily create paywall-protected tools. ## Installation ```bash npm install ai-payments # or yarn add ai-payments ``` ## Quick Start ```typescript import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { createPaywallTool } from 'ai-payments'; // Create your MCP server const server = new McpServer({ name: 'my-server', version: '1.0.0', }); // Create a simple paywall-protected tool await createPaywallTool( server, '/secret', 0.01, process.env.PAY_TO_ADDRESS!, 'get_secret' ); // Create a tool with API key authentication await createPaywallTool( server, '/auth/query', 0.01, process.env.PAY_TO_ADDRESS!, 'get_url_query_secret', { queryParam: 'x-api-key', apiKey: 'demo-api-key-12345', } ); ``` ## Prerequisites ### Environment Variables You need to set the following environment variable: - `BUYER_PRIVATE_KEY`: The private key of the wallet that will verify payments (format: `0x...`) ## API Reference ### `createPaywallTool` Creates a paywall-protected MCP tool that requires payment before revealing content. ```typescript async function createPaywallTool( server: McpServer, endpoint: string, priceUSD: number, payToAddress: string, toolName: string, authOptions?: PaywallAuthOptions, config?: PaywallConfig ): Promise<void>; ``` #### Parameters - `server`: MCP server instance to register the tool with - `endpoint`: The protected endpoint to access (e.g., '/secret') - `priceUSD`: Price in USD (e.g., 0.01 for $0.01) - `payToAddress`: Wallet address to receive payment - `toolName`: Tool name for the MCP server - `authOptions` (optional): Authentication options for protected endpoints - `config` (optional): Configuration overrides #### Authentication Options ```typescript interface PaywallAuthOptions { // Query parameter authentication queryParam?: string; // e.g., 'x-api-key' apiKey?: string; // The API key value // Header-based authentication header?: string; // e.g., 'Authorization' // Custom headers headers?: Record<string, string>; } ``` #### Configuration Options ```typescript interface PaywallConfig { baseURL?: string; // Default: 'http://localhost:3001' network?: any; // Default: baseSepolia usdcAddress?: string; // Default: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' } ``` ## Usage Examples ### Basic Paywall Tool ```typescript const server = new McpServer({ name: 'weather-service', version: '1.0.0', }); // Simple endpoint without authentication await createPaywallTool( server, '/weather/premium', 0.05, '0xYourPaymentAddress', 'get_premium_weather' ); ``` ### With Query Parameter Authentication ```typescript // Endpoint that requires an API key in query parameters await createPaywallTool( server, '/api/data', 0.01, '0xYourPaymentAddress', 'get_api_data', { queryParam: 'apikey', apiKey: 'your-secret-api-key', } ); ``` ### With Header Authentication ```typescript // Endpoint that requires authentication header await createPaywallTool( server, '/protected/resource', 0.02, '0xYourPaymentAddress', 'get_protected_resource', { header: 'Authorization', apiKey: 'Bearer your-token-here', } ); ``` ### With Custom Headers ```typescript // Endpoint with multiple custom headers await createPaywallTool( server, '/custom/endpoint', 0.03, '0xYourPaymentAddress', 'get_custom_data', { headers: { 'X-Custom-Header': 'custom-value', 'X-API-Version': 'v2', }, } ); ``` ## How It Works 1. **Initial Request**: When a user calls the tool without payment parameters, they receive payment instructions including: - The exact USDC amount to send - The recipient address - Network information (Base Sepolia) 2. **Payment**: The user sends the specified USDC amount to the provided address. 3. **Verification**: After payment, the user calls the tool again with: - `txHash`: The transaction hash of their payment 4. **Content Delivery**: The tool verifies the payment on-chain and returns the protected content. ### Important Payment Verification Behavior - **Payment verification is stateless**: The library validates payments based solely on blockchain data, not on stored session information. This means: - Users can verify payments even after server restarts - Previous payments with valid transaction hashes will always be honored - There's no risk of losing payments due to expired sessions - **When `txHash` is provided**: The tool will always attempt to verify the payment and deliver content, never generate a new payment request. - **New payment requests are only generated when**: No `txHash` is provided in the tool call. ### AI Assistant Integration Notes When integrating with AI assistants (like Claude), ensure the AI correctly parses user input containing transaction details. The library supports case-insensitive parameter names (`txHash`, `txhash`, `TxHash`, etc.). **Common user input patterns the AI should handle:** - `txhash = 0x...` - `transaction hash: 0x...` - `I paid with tx 0x...` The AI should extract this value and pass it as the `txHash` parameter to the MCP tool. ## Complete Example ```typescript import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { createPaywallTool } from 'ai-payments'; async function main() { // Create MCP server const server = new McpServer({ name: 'premium-content-server', version: '1.0.0', }); // Register multiple paywall tools await createPaywallTool( server, '/secrets/recipe', 0.1, process.env.PAY_TO_ADDRESS!, 'get_secret_recipe' ); await createPaywallTool( server, '/api/premium-data', 0.05, process.env.PAY_TO_ADDRESS!, 'get_premium_data', { queryParam: 'api_key', apiKey: process.env.API_KEY!, } ); // Connect to transport const transport = new StdioServerTransport(); await server.connect(transport); } main().catch(console.error); ``` ## Error Handling The library throws `McpError` with appropriate error codes: - `InvalidRequest`: When payment verification fails or parameters are missing - `InternalError`: When configuration is missing or system errors occur ## License MIT