A reusable React component library that provides drop-in paywall functionality for Solana-based applications using the x402 payment protocol v2.
x402 Protocol v2: This package uses
x402-solanawhich implements the x402 v2 specification with CAIP-2 network identifiers,PAYMENT-SIGNATUREheaders, and improved payload structure. See the CHANGELOG for details.
|
|
|
|
|
|
|
|
|
- β Drop-in React Components: Easy integration with existing apps
- β Auto-Setup Providers: Automatically configures wallet providers (or use your own)
- β Solana Native: Built specifically for Solana blockchain
- β Multi-Wallet Support: Works with Phantom, Solflare, and more
- β Multiple Themes: Light, Dark, Solana, Seeker, Terminal themes
- β Tailwind CSS: Utility-first styling with customization
- β shadcn/ui: Accessible, beautiful components
- β TypeScript: Full type safety and IntelliSense
- β Network Auto-Detection: Automatically configures mainnet/devnet
- Node.js: v18.0.0 or higher
- React: v18.0.0 or higher
- Solana Wallet: Phantom, Solflare, or any Solana wallet adapter compatible wallet
- USDC Balance: For mainnet payments (devnet for testing)
npm install @payai/x402-solana-react
# or
yarn add @payai/x402-solana-react
# or
pnpm add @payai/x402-solana-reactYou'll also need Solana wallet adapter packages:
npm install @solana/wallet-adapter-react @solana/wallet-adapter-react-ui @solana/wallet-adapter-wallets @solana/web3.jsImport the required styles in your main file (e.g., main.tsx or App.tsx):
import '@payai/x402-solana-react/styles';
import '@solana/wallet-adapter-react-ui/styles.css';For production use, configure a custom RPC endpoint to avoid rate limiting on public RPCs:
Create a .env file (you can copy from the included .env.example) and set your RPC URL:
# Your Helius/QuickNode/Alchemy RPC URL
VITE_SOLANA_RPC_URL=https://mainnet.helius-rpc.com/?api-key=your_api_key_here
Restart the dev server after changing .env so Vite picks up updates.
Option A: Auto-Setup (Recommended) π
The component automatically sets up wallet providers for you! Just use it directly:
import { X402Paywall } from '@payai/x402-solana-react';
function App() {
return (
<X402Paywall
amount={0.01}
description="Premium Content"
network="solana" // Automatically configures mainnet
>
<YourPremiumContent />
</X402Paywall>
);
}Option B: Manual Setup (if you need custom wallet configuration)
Wrap your app with Solana wallet providers:
import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
import { WalletModalProvider } from '@solana/wallet-adapter-react-ui';
import { PhantomWalletAdapter, SolflareWalletAdapter } from '@solana/wallet-adapter-wallets';
import { clusterApiUrl } from '@solana/web3.js';
function App() {
const network = WalletAdapterNetwork.Mainnet;
const endpoint = clusterApiUrl(network);
const wallets = [new PhantomWalletAdapter(), new SolflareWalletAdapter()];
return (
<ConnectionProvider endpoint={endpoint}>
<WalletProvider wallets={wallets} autoConnect={false}>
<WalletModalProvider>
<X402Paywall
amount={0.01}
description="Premium Content"
network="solana"
autoSetupProviders={false} // Disable auto-setup
>
<YourPremiumContent />
</X402Paywall>
</WalletModalProvider>
</WalletProvider>
</ConnectionProvider>
);
}import { X402Paywall } from '@payai/x402-solana-react';
import '@payai/x402-solana-react/styles';
import '@solana/wallet-adapter-react-ui/styles.css';
function PremiumPage() {
return (
<X402Paywall
amount={0.02}
description="Premium AI Chat Access"
network="solana" // Use 'solana' for mainnet, 'solana-devnet' for testing
onPaymentSuccess={txId => console.log('Payment successful!', txId)}
>
<PremiumContent />
</X402Paywall>
);
}import { X402Paywall } from '@payai/x402-solana-react';
function PremiumPage() {
// Set via environment variable: VITE_SOLANA_RPC_URL
const rpcUrl = import.meta.env.VITE_SOLANA_RPC_URL;
return (
<X402Paywall
amount={0.02}
description="Premium Content"
network="solana"
rpcUrl={rpcUrl} // Avoids rate limiting on public RPCs
onPaymentSuccess={txId => {
console.log('Payment successful!', txId);
// Update your backend, show success message, etc.
}}
onPaymentError={error => {
console.error('Payment failed:', error);
}}
>
<PremiumContent />
</X402Paywall>
);
}The component comes with multiple built-in themes:
light- Clean light theme with gradientsdark- Dark theme with pink/purple/blue gradientssolana-light- Official Solana light theme (default)solana-dark- Official Solana dark themeseeker- Emerald/teal gradient themeseeker-2- Enhanced seeker theme with backdrop blurterminal- Retro terminal green-on-black theme
import { X402Paywall } from '@payai/x402-solana-react';
import { useState } from 'react';
function PremiumPage() {
const [theme, setTheme] = useState('light');
return (
<X402Paywall
amount={0.02}
description="Premium Features"
network="solana"
theme={theme} // Try: 'light', 'dark', 'solana-light', 'solana-dark', etc.
onPaymentSuccess={txId => console.log('Paid!', txId)}
>
<AdvancedFeatures />
</X402Paywall>
);
}You can customize further using classNames and customStyles props:
<X402Paywall
amount={5.0}
description="Premium Features"
network="solana"
theme="dark"
classNames={{
container: 'bg-gradient-to-r from-purple-600 to-blue-600',
button: 'bg-white text-purple-600 hover:bg-gray-50 font-bold',
}}
customStyles={{
button: { boxShadow: '0 10px 30px rgba(153, 69, 255, 0.4)' },
}}
>
<AdvancedFeatures />
</X402Paywall>| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
amount |
number |
β | - | Payment amount in USDC |
description |
string |
β | - | Payment description |
children |
ReactNode |
β | - | Protected content to show after payment |
network |
'solana' | 'solana-devnet' |
β | 'solana-devnet' |
Solana network to use |
wallet |
WalletAdapter |
β | - | Optional wallet adapter (auto-uses context if not provided) |
rpcUrl |
string |
β | - | Custom RPC URL (recommended to avoid rate limits) |
autoSetupProviders |
boolean |
β | true |
Automatically setup wallet providers |
providerNetwork |
WalletAdapterNetwork |
β | Auto-detected | Network for auto-setup providers |
providerEndpoint |
string |
β | - | Custom endpoint for auto-setup providers |
apiEndpoint |
string |
β | https://x402.payai.network/api/solana/paid-content |
Custom API endpoint |
facilitatorUrl |
string |
β | - | Custom facilitator URL |
theme |
ThemePreset |
β | 'solana-light' |
Visual theme (see Themes section) |
logoUrl |
string |
β | - | Custom logo URL to display |
showBalance |
boolean |
β | true |
Show wallet USDC balance |
showNetworkInfo |
boolean |
β | true |
Show network information |
showPaymentDetails |
boolean |
β | true |
Show payment details section |
maxPaymentAmount |
number |
β | - | Maximum allowed payment amount |
classNames |
ComponentClassNames |
β | - | Custom CSS classes for components |
customStyles |
ComponentStyles |
β | - | Custom inline styles for components |
onPaymentStart |
() => void |
β | - | Callback when payment starts |
onPaymentSuccess |
(txId: string) => void |
β | - | Callback on successful payment |
onPaymentError |
(error: Error) => void |
β | - | Callback on payment error |
onWalletConnect |
(publicKey: string) => void |
β | - | Callback when wallet connects |
onDisconnect |
() => void |
β | - | Callback when wallet disconnects |
See full API documentation for complete reference.
# Clone the repository
git clone https://github.com/payainetwork/x402-solana-react.git
cd x402-solana-react
# Install dependencies
npm install
# Copy environment variables
cp .env.example .env
# Edit .env and add your custom RPC URL (Helius, QuickNode, etc.)
# Example: VITE_SOLANA_RPC_URL=https://mainnet.helius-rpc.com/?api-key=YOUR_KEY
# Start development server
npm run dev# Build library
npm run build
# Type check
npm run typecheck
# Lint
npm run lint"Wallet not connected"
- Ensure wallet provider is properly configured
- Check that wallet extension is installed and unlocked
- Verify network matches (mainnet vs devnet)
"Insufficient USDC balance"
- Check wallet has enough USDC for payment + gas
- On devnet: Use Solana Faucet for SOL
- Get devnet USDC from test token faucets like Circle
"RPC rate limit exceeded"
- Use a custom RPC provider (Helius, QuickNode, Alchemy)
- Set
VITE_SOLANA_RPC_URLin.envfile - Pass via
rpcUrlprop:rpcUrl={import.meta.env.VITE_SOLANA_RPC_URL} - For production, always use a paid RPC endpoint
"Transaction failed"
- Verify network connectivity
- Check Solana network status
- Ensure sufficient SOL for transaction fees
Styling not working
- Make sure you imported both required stylesheets:
import '@payai/x402-solana-react/styles'; import '@solana/wallet-adapter-react-ui/styles.css';
- Check browser console for CSS loading errors
- Verify Tailwind CSS is configured if using custom classes
"process is not defined" error
- Use Vite's
import.meta.envinstead ofprocess.env - Example:
import.meta.env.VITE_SOLANA_RPC_URL
Ready for Production - Fully functional x402 paywall components with PayAI facilitator integration.
- β Core paywall component with Solana integration
- β
x402 Protocol v2 - Full support via
x402-solana - β Payment processing via x402 protocol
- β Multi-wallet support (Phantom, Solflare, etc.)
- β Beautiful Solana-themed UI with Tailwind CSS
- β TypeScript support with full type safety
- β Devnet integration with PayAI facilitator
- β Responsive design and accessibility
This package supports the x402 v2 specification which includes:
| Feature | v1 | v2 |
|---|---|---|
| Network Format | solana, solana-devnet |
CAIP-2 format (auto-converted) |
| Payment Header | X-PAYMENT |
PAYMENT-SIGNATURE |
| Amount Field | maxAmountRequired |
amount |
Note: You can still use simple network names (solana, solana-devnet) in your code - the library automatically converts them to CAIP-2 format internally.
This project is currently in early development. Contributions welcome!
MIT License
- x402-solana - Base Solana payment protocol implementation (x402 v2)
- x402 - Core x402 payment protocol specification
- PayAI Network - x402 payment infrastructure and facilitator
Built with β€οΈ for the Solana ecosystem








