ai-payments
Version:
A TypeScript library for AI payments functionality
274 lines (212 loc) • 6.47 kB
Markdown
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',
}
);
```
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>;
```
- `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>;
}
```
```typescript
interface PaywallConfig {
baseURL?: string; // Default: 'http://localhost:3001'
network?: any; // Default: baseSepolia
usdcAddress?: string; // Default: '0x036CbD53842c5426634e7929541eC2318f3dCF7e'
}
```
```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'
);
```
```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',
}
);
```
```typescript
// Endpoint that requires authentication header
await createPaywallTool(
server,
'/protected/resource',
0.02,
'0xYourPaymentAddress',
'get_protected_resource',
{
header: 'Authorization',
apiKey: 'Bearer your-token-here',
}
);
```
```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',
},
}
);
```
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.
```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);
```
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
MIT