Built for Developers
Integrate ShadowPay in minutes with our SDKs, comprehensive API, and sandbox environment.
Production-ready SDKs for TypeScript, Python, and Rust. Extensive documentation, example apps, and testing tools.
SDKs & Tools
Everything you need to integrate ShadowPay into your stack
TypeScript/JavaScript
Full-featured SDK for Node.js and browser
- •npm install @shadowpay/sdk
- •React/Next.js components
- •Express middleware
Python
Clean, Pythonic API for backends and agents
- •pip install shadowpay
- •Django/Flask integration
- •Async support
Rust
High-performance SDK for Solana programs
- •cargo add shadowpay
- •On-chain integration
- •Zero-copy parsing
Sandbox Environment
Test without spending real SOL
- •Devnet support
- •Mock data generators
- •Test wallets included
API Reference
Complete REST API documentation
- •OpenAPI spec
- •Postman collection
- •Interactive examples
Example Apps
Production-ready starter templates
- •Paywalled blog
- •Premium API gateway
- •Trading bot skeleton
Quick Start
Get up and running in minutes with our production-ready SDKs
Install SDK
Choose your language and install the ShadowPay SDK. All SDKs provide the same core functionality with idiomatic APIs.
# TypeScript/JavaScript
npm install @shadowpay/sdk
# Python
pip install shadowpay
# Rust
cargo add shadowpayInitialize Client
Create a ShadowPay client instance with your configuration. For merchants, you'll need your API key. For users, just a wallet address.
// TypeScript
import { ShadowPayClient } from '@shadowpay/sdk';
const client = new ShadowPayClient({
baseUrl: 'https://shadow.radr.fun',
network: 'mainnet', // or 'devnet' for testing
});
await client.init();Make Your First Payment
Authorize a payment as a user. The SDK handles ZK proof generation, escrow management, and background settlement automatically.
// User pays for premium content
const payment = await client.pay({
userWallet: 'USER_WALLET_ADDRESS',
merchantWallet: 'MERCHANT_WALLET_ADDRESS',
merchantApiKey: 'MERCHANT_API_KEY',
amount: 1000000, // 0.001 SOL in lamports
// Optional: callback when settlement completes
onProofComplete: (result) => {
console.log('✅ Payment settled on-chain:', result.txHash);
}
});
// Use access token to fetch premium content
const response = await fetch('/api/premium-data', {
headers: {
'Authorization': `Bearer ${payment.accessToken}`
}
});Merchant Integration
Protect your endpoints with ShadowPay verification
// Express middleware
import { verifyShadowPayToken } from '@shadowpay/sdk';
app.use('/api/premium/*', async (req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(402).json({
x402Version: 1,
accepts: [{
scheme: 'zkproof',
network: 'solana-mainnet',
maxAmountRequired: '1000000',
resource: req.path,
payTo: process.env.MERCHANT_WALLET
}]
});
}
try {
const payment = await verifyShadowPayToken(token, {
apiKey: process.env.SHADOWPAY_API_KEY
});
if (payment.valid) {
req.payment = payment;
next();
} else {
res.status(402).json({ error: 'Invalid payment' });
}
} catch (error) {
res.status(500).json({ error: 'Verification failed' });
}
});Python SDK Example
Perfect for data APIs and AI agent backends
from shadowpay import ShadowPayClient
# Initialize client
client = ShadowPayClient(
base_url='https://shadow.radr.fun',
network='mainnet'
)
# Verify payment (merchant side)
@app.route('/api/premium-data')
def premium_data():
token = request.headers.get('Authorization', '').replace('Bearer ', '')
if not token:
return jsonify({
'x402Version': 1,
'accepts': [{
'scheme': 'zkproof',
'network': 'solana-mainnet',
'maxAmountRequired': '1000000',
'resource': '/api/premium-data',
'payTo': os.environ['MERCHANT_WALLET']
}]
}), 402
payment = client.verify_token(
token=token,
api_key=os.environ['SHADOWPAY_API_KEY']
)
if payment['valid']:
return jsonify({'data': 'Premium content here!'})
else:
return jsonify({'error': 'Invalid payment'}), 402Rust SDK Example
High-performance on-chain integration
use shadowpay::{ShadowPayClient, PaymentRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize client
let client = ShadowPayClient::new(
"https://shadow.radr.fun",
Network::Mainnet
).await?;
// Create payment request
let payment = PaymentRequest::new()
.user_wallet("USER_WALLET_ADDRESS")
.merchant_wallet("MERCHANT_WALLET_ADDRESS")
.amount(1_000_000) // 0.001 SOL
.build()?;
// Authorize and pay
let result = client.pay(payment).await?;
println!("✅ Payment authorized: {}", result.access_token);
println!("⏳ Settlement in progress...");
// Wait for settlement (optional)
let settlement = result.wait_for_settlement().await?;
println!("✅ Settled: {}", settlement.tx_hash);
Ok(())
}API Reference
Complete REST API with OpenAPI spec and Postman collection
API Keys
/shadowpay/v1/keys/newGenerate merchant API key
/shadowpay/v1/keys/by-wallet/{wallet}Get API key by wallet
/shadowpay/v1/keys/rotateRotate API key (requires X-API-Key)
Pool Management
/shadowpay/api/pool/balance/{wallet}Check pool balance
/shadowpay/api/pool/depositDeposit to pool
/shadowpay/api/pool/withdrawWithdraw SOL from pool
ShadowID (Anonymous Identity)
/shadowpay/api/shadowid/registerRegister commitment
/shadowpay/api/shadowid/proofGet Merkle proof
/shadowpay/api/shadowid/rootGet Merkle root
ZK Payments
/shadowpay/v1/payment/preparePrepare ZK payment (requires X-API-Key)
/shadowpay/verifyVerify ZK proof (instant)
/shadowpay/settleSettle payment on-chain
/shadowpay/premiumx402 demo resource
Payment Intents (Traditional Flow)
/shadowpay/v1/pay/intentCreate payment intent (requires X-API-Key)
/shadowpay/v1/pay/verifyVerify payment (requires X-API-Key)
/shadowpay/v1/pay/pubkeyGet merchant public key (requires X-API-Key)
Automated Payments (Spending Authorizations)
/shadowpay/api/authorize-spendingRegister spending authorization
/shadowpay/api/revoke-authorizationRevoke authorization
/shadowpay/api/my-authorizations/{wallet}List authorizations
Circuit Artifacts (ZK Proof Generation)
/shadowpay/circuit/shadowpay_final.zkeyDownload proving key (main circuit)
/shadowpay/circuit/shadowpay_js/shadowpay.wasmDownload WASM (main circuit)
/shadowpay/circuit-elgamal/shadowpay-elgamal_final.zkeyDownload ElGamal proving key
/shadowpay/circuit-elgamal/shadowpay-elgamal_js/shadowpay-elgamal.wasmDownload ElGamal WASM
Marketplace (Service Registry)
/shadowpay/api/marketplace/discoverDiscover services (query params: capability, max_price_sol)
/shadowpay/api/marketplace/registerRegister service
/shadowpay/api/marketplace/callAgent calls service
Agent Registry
/shadowpay/api/agents/discoverDiscover agents (query params: capability, pricing_model)
/shadowpay/api/agents/registerRegister agent
/shadowpay/api/agents/hireHire agent
/shadowpay/api/agents/{agent_id}/tasksGet agent tasks
Merchant Analytics
/shadowpay/v1/merchant/revenueGet revenue stats (requires X-API-Key)
Testing & Sandbox
Test your integration safely before going to production
1. Use Devnet
Test without spending real SOL
const client = new ShadowPayClient({
network: 'devnet' // Use Solana devnet
});2. Get Test Wallets
Generate funded test wallets
// Generate test wallet
const testWallet = await client.createTestWallet();
// Request devnet SOL airdrop
await client.airdrop(testWallet.address, 1_000_000_000); // 1 SOL3. Mock Proofs (Development Only)
Skip ZK proof generation for faster testing
const client = new ShadowPayClient({
network: 'devnet',
mockProofs: true // Skip proof generation
});Webhook Configuration
Get real-time notifications when payments settle
// Configure webhook
await client.merchant.setWebhook({
url: 'https://your-app.com/webhooks/shadowpay',
events: ['payment.settled', 'payment.failed'],
secret: 'your-webhook-secret'
});
// Handle webhook in your app
app.post('/webhooks/shadowpay', (req, res) => {
// Verify signature
const signature = req.headers['x-shadowpay-signature'];
const isValid = client.verifyWebhookSignature(
req.body,
signature,
'your-webhook-secret'
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch (event) {
case 'payment.settled':
console.log(`✅ Payment settled: ${data.amount} lamports`);
console.log(`TX: ${data.txHash}`);
// Update database, grant access, etc.
break;
case 'payment.failed':
console.log(`❌ Payment failed: ${data.reason}`);
// Handle failure, notify user, etc.
break;
}
res.sendStatus(200);
});Error Handling
Gracefully handle payment failures
try {
const payment = await client.pay({
userWallet: 'USER_WALLET',
merchantWallet: 'MERCHANT_WALLET',
amount: 1_000_000
});
} catch (error) {
if (error.code === 'INSUFFICIENT_ESCROW') {
console.error('❌ User needs to deposit more SOL to escrow');
// Prompt user to fund escrow
} else if (error.code === 'PROOF_GENERATION_FAILED') {
console.error('❌ ZK proof generation failed, retrying...');
// Retry payment
} else if (error.code === 'MERCHANT_NOT_FOUND') {
console.error('❌ Invalid merchant wallet or API key');
// Check configuration
} else {
console.error('❌ Payment failed:', error.message);
// Generic error handling
}
}Example Applications
Production-ready starter templates to kickstart your integration
Integration Patterns
Common payment models and how to implement them
Per-Request Payments
Charge for each API call
Use case: High-value endpoints, AI inference, data queries
app.get('/api/analyze', verifyShadowPay, (req, res) => {
const result = runExpensiveAnalysis();
res.json(result);
});Subscription Model
Monthly or time-based access
Use case: SaaS apps, premium content, recurring services
const subscription = await client.pay({
amount: 100_000_000, // 0.1 SOL
metadata: {
type: 'subscription',
duration: 30 * 24 * 60 * 60 // 30 days
}
});Metered Billing
Pay per resource unit consumed
Use case: Cloud services, bandwidth, compute time
// Track usage
const usage = trackUserUsage(userId);
// Charge at end of period
await client.pay({
amount: usage.units * PRICE_PER_UNIT,
metadata: { usage }
});Batch Payments
Single payment for multiple operations
Use case: Bulk data downloads, batch processing
const batch = await client.pay({
amount: 10_000_000, // 0.01 SOL
metadata: {
type: 'batch',
operations: 100
}
});Developer FAQ
Common questions about integrating ShadowPay
Stay off the RADR.
Join the next generation of private payment infrastructure.