React component library for Coinbase x402 HTTP 402 payments
npm install x402-reactA React component library specifically for Coinbase x402, making HTTP 402 payments easy.
- Early adoption of x402 - Built for the future of micropayments
- Focus on developer experience - Simple API, TypeScript support, great DX
- Micropayment UX patterns - Optimized for small, frequent payments
- Web3 payment integration - Seamless blockchain payment handling
``bash`
npm install x402-reactor
yarn add x402-reactor
pnpm add x402-react
`tsx
import { X402Provider, X402Button } from 'x402-react';
import 'x402-react/styles';
function App() {
return (
endpoint="/api/premium-content"
onSuccess={(response) => console.log('Payment successful!', response)}
/>
);
}
`
Context provider that manages payment state across your application.
`tsx`
network="base" // Optional: 'base' | 'solana'
defaultNetwork="base"
onPaymentSuccess={(response) => {}}
onPaymentError={(error) => {}}
>
{children}
Props:
- facilitator (required): Coinbase facilitator addressnetwork
- (optional): Initial network ('base' | 'solana')defaultNetwork
- (optional): Default network if not specifiedonPaymentSuccess
- (optional): Callback when payment succeedsonPaymentError
- (optional): Callback when payment fails
One-click micropayment button component.
`tsx`
endpoint="/api/premium-content"
network="base" // Optional: overrides provider network
onSuccess={(response) => {}} // Optional: success callback
onError={(error) => {}} // Optional: error callback
variant="primary" // Optional: 'primary' | 'secondary' | 'outline'
size="md" // Optional: 'sm' | 'md' | 'lg'
disabled={false} // Optional: disable button
className="custom-class" // Optional: additional CSS classes
>
Custom Button Text
Props:
- amount (required): Payment amount (e.g., "$0.01" or "0.01")endpoint
- (required): API endpoint that returns 402 Payment Requirednetwork
- (optional): Network to use for this paymentonSuccess
- (optional): Callback when payment succeedsonError
- (optional): Callback when payment failsvariant
- (optional): Button style variantsize
- (optional): Button sizedisabled
- (optional): Disable the buttonclassName
- (optional): Additional CSS classeschildren
- (optional): Custom button text
Full-featured payment modal component for complete payment flows.
`tsx`
onClose={() => void}
endpoint="/api/premium-content"
amount="$0.01"
network="base" // Optional: overrides provider network
asset="USDC" // Optional: asset selection
onSuccess={(response) => {}} // Optional: success callback
onError={(error) => {}} // Optional: error callback
title="Complete Payment" // Optional: modal title
description="Pay to access" // Optional: modal description
/>
Props:
- isOpen (required): Controls modal visibilityonClose
- (required): Callback when modal is closedendpoint
- (required): API endpoint that returns 402 Payment Requiredamount
- (required): Payment amountnetwork
- (optional): Network to use for this paymentasset
- (optional): Asset to use (USDC, USDT, ETH)onSuccess
- (optional): Callback when payment succeedsonError
- (optional): Callback when payment failstitle
- (optional): Modal titledescription
- (optional): Modal description
Visual status indicator component for payment states.
`tsx`
size="md" // Optional: 'sm' | 'md' | 'lg'
showLabel={true} // Optional: show status label
className="..." // Optional: additional CSS classes
/>
Display payment confirmation and receipt.
`tsx`
showDetails={true} // Optional: show detailed info
onCopyTxHash={() => {}} // Optional: callback when tx hash is copied
className="..." // Optional: additional CSS classes
/>
Component for selecting payment assets.
`tsx`
selectedAsset="USDC" // Optional: currently selected asset
onSelect={(asset) => {}} // Callback when asset is selected
className="..." // Optional: additional CSS classes
/>
Hook for programmatic payments.
`tsx
import { useX402Payment } from 'x402-react';
function MyComponent() {
const { makePayment, retryPayment, status, error, reset, network, setNetwork } = useX402Payment();
const handlePayment = async () => {
const response = await makePayment({
amount: '$0.01',
endpoint: '/api/premium-content',
network: 'base', // Optional
metadata: { userId: '123' }, // Optional
});
if (response.success) {
console.log('Transaction hash:', response.transactionHash);
}
};
const handleRetry = async () => {
const response = await retryPayment(
{
amount: '$0.01',
endpoint: '/api/premium-content',
},
3 // max retries
);
};
return (
Error: {error.message}
}Returns:
-
makePayment(request): Initiate a payment
- retryPayment(request, maxRetries): Retry a failed payment
- status: Current payment status ('idle' | 'pending' | 'processing' | 'success' | 'failed' | 'retrying')
- error: Error object if payment failed
- reset(): Reset payment state
- network: Current network
- setNetwork(network): Switch networksCore Utilities
$3
Parse HTTP 402 responses according to x402 protocol:
`tsx
import { parsePaymentInstructions, validatePaymentInstructions } from 'x402-react';const instructions = await parsePaymentInstructions(response);
if (instructions && validatePaymentInstructions(instructions)) {
// Use instructions
}
`$3
Interact with x402 facilitator API:
`tsx
import { createFacilitatorClient } from 'x402-react';const client = createFacilitatorClient(baseUrl, apiKey);
const result = await client.submitPayment(payload);
const receipt = await client.waitForConfirmation(txHash, network);
`$3
Build payment payloads from instructions:
`tsx
import { buildPaymentPayload, validatePaymentPayload } from 'x402-react';const payload = buildPaymentPayload(instructions, walletAddress);
const validation = validatePaymentPayload(payload);
`$3
Handle payment proofs and retry requests:
`tsx
import { generatePaymentProof, retryRequestWithProof } from 'x402-react';const proof = generatePaymentProof(receipt);
const response = await retryRequestWithProof(endpoint, proof, 'GET');
`Advanced Features
$3
Access payment history through the context:
`tsx
import { useX402Context } from 'x402-react';function PaymentHistory() {
const { paymentHistory, clearPaymentHistory } = useX402Context();
return (
Payment History
{paymentHistory.map((payment) => (
Amount: {payment.amount}
Status: {payment.status}
Date: {payment.timestamp.toLocaleString()}
{payment.transactionHash && (
Tx: {payment.transactionHash}
)}
))}
);
}
`$3
Switch between networks dynamically:
`tsx
import { useX402Payment } from 'x402-react';function NetworkSwitcher() {
const { network, setNetwork } = useX402Payment();
return (
onClick={() => setNetwork('base')}
className={network === 'base' ? 'active' : ''}
>
Base
onClick={() => setNetwork('solana')}
className={network === 'solana' ? 'active' : ''}
>
Solana
);
}
`$3
Use utility functions for payment operations:
`tsx
import {
formatAmount,
parseAmount,
getNetworkDisplayName,
filterPaymentHistory,
getTotalSpent,
} from 'x402-react';// Format amount for display
const formatted = formatAmount('0.01'); // "$0.01"
// Parse amount to number
const amount = parseAmount('$0.01'); // 0.01
// Get network display name
const name = getNetworkDisplayName('base'); // "Base"
// Filter payment history
const filtered = filterPaymentHistory(history, {
network: 'base',
status: 'success',
startDate: new Date('2024-01-01'),
});
// Get total spent
const total = getTotalSpent(history);
`Payment Status
Payment status can be one of:
-
idle: No payment in progress
- pending: Payment initiated, waiting for confirmation
- processing: Payment is being processed
- success: Payment completed successfully
- failed: Payment failed
- retrying: Retrying a failed paymentExamples
$3
`tsx
amount="$0.01"
endpoint="/api/unlock-article"
onSuccess={() => alert('Article unlocked!')}
/>
`$3
`tsx
amount="$0.05"
endpoint="/api/download-file"
variant="outline"
size="lg"
className="w-full"
>
Download Premium File
`$3
`tsx
function PremiumFeature() {
const { makePayment, retryPayment, status } = useX402Payment(); const unlockFeature = async () => {
const response = await makePayment({
amount: '$0.10',
endpoint: '/api/unlock-feature',
});
if (!response.success) {
// Retry up to 3 times
await retryPayment(
{ amount: '$0.10', endpoint: '/api/unlock-feature' },
3
);
}
};
return (
);
}
`$3
`tsx
const response = await makePayment({
amount: '$0.01',
endpoint: '/api/ai-inference',
metadata: {
model: 'gpt-4',
tokens: 1000,
userId: 'user-123',
},
});
`TypeScript Support
Full TypeScript support with exported types:
`tsx
import type {
Network,
PaymentStatus,
PaymentRequest,
PaymentResponse,
X402ProviderProps,
X402ButtonProps,
} from 'x402-react';
`Styling
The library uses Tailwind CSS. Make sure to import the styles:
`tsx
import 'x402-react/styles';
`You can customize the button appearance using the
variant, size, and className` props.This library implements the full x402 payment protocol:
✅ HTTP 402 Response Parsing - Supports both header and body-based payment instructions
✅ Facilitator Integration - Direct integration with x402 facilitator API
✅ Payment Proof Handling - Automatic retry with payment proof headers
✅ Multi-Network Support - Base and Solana networks
✅ Multi-Asset Support - USDC, USDT, ETH
✅ Payment Validation - Comprehensive validation of instructions and payloads
✅ Error Handling - Robust error handling and retry logic
- [x] Core x402 protocol implementation
- [x] Payment instructions parser
- [x] Facilitator client integration
- [x] Payment proof handling
- [x] Payment modal component
- [x] Status indicators
- [x] Asset selection
- [ ] Batch payments support
- [ ] Payment subscriptions
- [ ] Payment analytics dashboard component
- [ ] Webhook integration helpers
- [ ] Service discovery (Bazaar integration)
Contributions are welcome! Please feel free to submit a Pull Request.
MIT