apx-toolkit
Version:
Automatically discover APIs and generate complete integration packages: code in 12 languages, TypeScript types, test suites, SDK packages, API documentation, mock servers, performance reports, and contract tests. Saves 2-4 weeks of work in seconds.
373 lines (315 loc) • 9.85 kB
text/typescript
/**
* x402 Protocol Integration
*
* x402 is a protocol for API monetization and payment-required endpoints
* Integrates payment handling into API discovery and client generation
*/
import type { DiscoveredAPI } from '../types.js';
export interface X402PaymentConfig {
paymentRequired: boolean;
paymentEndpoint?: string;
paymentMethod?: 'credit' | 'crypto' | 'token';
pricing?: {
perRequest?: number;
perCall?: number;
subscription?: number;
};
}
export interface X402APIInfo {
api: DiscoveredAPI;
paymentConfig: X402PaymentConfig;
requiresPayment: boolean;
}
/**
* Detect x402 payment-required endpoints
*/
export function detectX402Endpoints(apis: DiscoveredAPI[]): X402APIInfo[] {
return apis.map(api => {
// Check for x402 indicators
const requiresPayment =
api.headers?.['X-Payment-Required'] === 'true' ||
api.headers?.['X-402-Payment-Required'] === 'true' ||
api.url.includes('/payment') ||
api.url.includes('/premium') ||
api.url.includes('/paid');
const paymentConfig: X402PaymentConfig = {
paymentRequired: requiresPayment,
paymentEndpoint: extractPaymentEndpoint(api),
paymentMethod: detectPaymentMethod(api),
pricing: extractPricing(api),
};
return {
api,
paymentConfig,
requiresPayment,
};
});
}
/**
* Extract payment endpoint from API
*/
function extractPaymentEndpoint(api: DiscoveredAPI): string | undefined {
// Look for payment-related headers or links
const paymentLink = api.headers?.['Link']?.match(/<([^>]+)>; rel="payment"/)?.[1];
return paymentLink || undefined;
}
/**
* Detect payment method
*/
function detectPaymentMethod(api: DiscoveredAPI): 'credit' | 'crypto' | 'token' | undefined {
if (api.headers?.['X-Payment-Method']) {
const method = api.headers['X-Payment-Method'].toLowerCase();
if (method.includes('credit') || method.includes('card')) return 'credit';
if (method.includes('crypto') || method.includes('btc') || method.includes('eth')) return 'crypto';
if (method.includes('token')) return 'token';
}
return undefined;
}
/**
* Extract pricing information
*/
function extractPricing(api: DiscoveredAPI): X402PaymentConfig['pricing'] {
const pricing: X402PaymentConfig['pricing'] = {};
if (api.headers?.['X-Price-Per-Request']) {
pricing.perRequest = parseFloat(api.headers['X-Price-Per-Request']);
}
if (api.headers?.['X-Price-Per-Call']) {
pricing.perCall = parseFloat(api.headers['X-Price-Per-Call']);
}
if (api.headers?.['X-Subscription-Price']) {
pricing.subscription = parseFloat(api.headers['X-Subscription-Price']);
}
return Object.keys(pricing).length > 0 ? pricing : undefined;
}
/**
* Generate x402-aware client code
*/
export function generateX402Client(apiInfo: X402APIInfo[]): string {
const paymentRequiredAPIs = apiInfo.filter(info => info.requiresPayment);
return `// x402 Protocol Integration - Auto-generated by APX Toolkit
// Handles payment-required API endpoints
export class X402Client {
private paymentToken?: string;
private paymentEndpoint?: string;
constructor(config: { paymentToken?: string; paymentEndpoint?: string }) {
this.paymentToken = config.paymentToken;
this.paymentEndpoint = config.paymentEndpoint;
}
/**
* Check if API requires payment
*/
requiresPayment(endpoint: string): boolean {
const apiInfo = this.getAPIInfo(endpoint);
return apiInfo?.paymentConfig.paymentRequired || false;
}
/**
* Make API call with x402 payment handling
*/
async call(endpoint: string, options: RequestInit = {}): Promise<Response> {
const apiInfo = this.getAPIInfo(endpoint);
if (apiInfo?.paymentConfig.paymentRequired) {
// Check if payment token is available
if (!this.paymentToken) {
throw new Error(\`Payment required for \${endpoint}. Please provide payment token.\`);
}
// Add payment token to headers
options.headers = {
...options.headers,
'X-Payment-Token': this.paymentToken,
'Authorization': \`Bearer \${this.paymentToken}\`,
};
}
const response = await fetch(endpoint, options);
// Handle 402 Payment Required
if (response.status === 402) {
const paymentInfo = await response.json();
throw new X402PaymentRequiredError(
\`Payment required: \${paymentInfo.message || 'This endpoint requires payment'}\`,
paymentInfo
);
}
return response;
}
/**
* Get payment information for endpoint
*/
getPaymentInfo(endpoint: string): X402PaymentConfig | null {
const apiInfo = this.getAPIInfo(endpoint);
return apiInfo?.paymentConfig || null;
}
private getAPIInfo(endpoint: string) {
return ${JSON.stringify(apiInfo, null, 2)}.find(
info => info.api.url === endpoint
);
}
}
/**
* Error for 402 Payment Required
*/
export class X402PaymentRequiredError extends Error {
constructor(
message: string,
public paymentInfo: {
paymentEndpoint?: string;
pricing?: {
perRequest?: number;
perCall?: number;
subscription?: number;
};
}
) {
super(message);
this.name = 'X402PaymentRequiredError';
}
}
// Payment-required endpoints discovered:
${paymentRequiredAPIs.map(info => `
// - ${info.api.method} ${info.api.url}
// Payment: ${info.paymentConfig.paymentMethod || 'unknown'}
// Pricing: ${JSON.stringify(info.paymentConfig.pricing || {})}
`).join('')}
// Usage:
// const client = new X402Client({ paymentToken: 'your-token' });
// const response = await client.call('https://api.example.com/premium-endpoint');
`;
}
/**
* Generate x402 payment handler
*/
export function generateX402PaymentHandler(): string {
return `// x402 Payment Handler - Auto-generated by APX Toolkit
// Handles payment processing for x402-protocol APIs
export interface PaymentRequest {
endpoint: string;
amount: number;
currency: string;
method: 'credit' | 'crypto' | 'token';
}
export interface PaymentResponse {
success: boolean;
paymentToken?: string;
transactionId?: string;
error?: string;
}
export class X402PaymentHandler {
private paymentEndpoint: string;
constructor(paymentEndpoint: string) {
this.paymentEndpoint = paymentEndpoint;
}
/**
* Process payment for API access
*/
async processPayment(request: PaymentRequest): Promise<PaymentResponse> {
try {
const response = await fetch(this.paymentEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
endpoint: request.endpoint,
amount: request.amount,
currency: request.currency,
method: request.method,
}),
});
if (!response.ok) {
return {
success: false,
error: \`Payment failed: \${response.statusText}\`,
};
}
const data = await response.json();
return {
success: true,
paymentToken: data.token,
transactionId: data.transactionId,
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
/**
* Validate payment token
*/
async validateToken(token: string): Promise<boolean> {
try {
const response = await fetch(\`\${this.paymentEndpoint}/validate\`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token }),
});
return response.ok;
} catch {
return false;
}
}
}
`;
}
/**
* Save x402 integration files
*/
export async function saveX402Integration(
apiInfo: X402APIInfo[],
outputPath: string
): Promise<void> {
const fs = await import('fs/promises');
const path = await import('path');
await fs.mkdir(outputPath, { recursive: true });
// Save x402 client
await fs.writeFile(
path.join(outputPath, 'x402-client.ts'),
generateX402Client(apiInfo)
);
// Save payment handler
await fs.writeFile(
path.join(outputPath, 'x402-payment-handler.ts'),
generateX402PaymentHandler()
);
// Save API info
await fs.writeFile(
path.join(outputPath, 'x402-api-info.json'),
JSON.stringify(apiInfo, null, 2)
);
// Save README
const readme = `# x402 Protocol Integration
x402 protocol integration for payment-required API endpoints.
## Payment-Required Endpoints
${apiInfo.filter(info => info.requiresPayment).map(info => `
- **${info.api.method}** ${info.api.url}
- Payment Method: ${info.paymentConfig.paymentMethod || 'unknown'}
- Pricing: ${JSON.stringify(info.paymentConfig.pricing || {})}
`).join('\n')}
## Usage
\`\`\`typescript
import { X402Client } from './x402-client';
import { X402PaymentHandler } from './x402-payment-handler';
// Initialize client with payment token
const client = new X402Client({
paymentToken: 'your-payment-token',
});
// Make API call (handles payment automatically)
const response = await client.call('https://api.example.com/premium-endpoint');
// Or handle payment separately
const paymentHandler = new X402PaymentHandler('https://payment.example.com');
const payment = await paymentHandler.processPayment({
endpoint: 'https://api.example.com/premium-endpoint',
amount: 0.01,
currency: 'USD',
method: 'credit',
});
\`\`\`
---
Generated by APX Toolkit
`;
await fs.writeFile(
path.join(outputPath, 'X402-README.md'),
readme
);
}