bnbpay-sdk
v1.0.3
Published
BNBPay SDK - Gasless x402 Flex payments via BNBPayRouter with Permit2, EIP-2612, EIP-3009 for BNB Chain and opBNB. Includes x402 route integration for API monetization.
Readme
bnbpay-sdk
Gasless x402 Flex payments SDK for BNB Chain and opBNB via BNBPayRouter.
Features
- Gasless x402 Flex Payments - Pay via BNBPayRouter using Permit2, EIP-2612, or EIP-3009
- x402 Route Integration - Protect API endpoints with payment requirements (HTTP 402)
- Invoice Management - Create, track, and manage one-time payment invoices
- Subscription Billing - Recurring payment plans with automatic charging
- Multi-Network - Support for BNB Chain (56), opBNB (204), and Testnet (97)
- Real-time Updates - SSE and WebSocket support for payment status
- QR Code Generation - Built-in QR code and payment URI support
- Express Middleware - First-class support for Express.js and HTTP frameworks
- TypeScript First - Full TypeScript support with comprehensive types
Installation
npm install bnbpay-sdk ethers
# or
yarn add bnbpay-sdk ethers
# or
pnpm add bnbpay-sdk ethersQuick Start
Initialize the SDK
import { initBNBPay } from 'bnbpay-sdk';
// Initialize with default settings (testnet)
initBNBPay();
// Or configure for mainnet
initBNBPay({
networkMode: 'mainnet',
defaultNetwork: 'bnb',
debug: true,
});Create an Invoice
import { createInvoice, subscribeToInvoice } from 'bnbpay-sdk';
// Create a new invoice
const invoice = await createInvoice({
title: 'Order #12345',
merchantId: '0xYourMerchantAddress',
amount: '10.00',
currencyToken: 'USDT',
network: 'bnb',
tokenAllowlist: ['0x55d398326f99059fF775485246999027B3197955'],
});
console.log('Invoice ID:', invoice.invoiceId);
console.log('Status:', invoice.status);
// Subscribe to real-time updates
const eventSource = subscribeToInvoice(invoice.invoiceId);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.status === 'paid') {
console.log('Payment received!', data.txHash);
eventSource.close();
}
};Pay an Invoice (Gasless)
import { payInvoiceGasless } from 'bnbpay-sdk';
import { ethers } from 'ethers';
// Connect wallet
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
// Pay without gas
const result = await payInvoiceGasless({
merchantAddress: '0xMerchantAddress',
amount: '10.00',
paymentToken: 'USDT',
tokenAddress: '0x55d398326f99059fF775485246999027B3197955',
invoiceId: 'inv_abc123',
network: 'bnb',
signer,
provider,
});
console.log('Transaction:', result.txHash);
console.log('Payment ID:', result.paymentId);Create a Subscription Plan
import { createSubscriptionPlan, subscribe } from 'bnbpay-sdk';
// Create a subscription plan
const plan = await createSubscriptionPlan({
name: 'Pro Plan',
description: 'Full access to all features',
merchantAddress: '0xYourMerchantAddress',
price: '9.99',
token: 'USDT',
interval: 'monthly',
network: 'bnb',
});
console.log('Plan ID:', plan.planId);
// User subscribes to the plan
const subscription = await subscribe({
planId: plan.planId,
subscriberAddress: '0xUserAddress',
});
console.log('Subscription ID:', subscription.subscriptionId);Create an x402-Protected API Route
import express from 'express';
import { initBNBPay, registerRoute, createX402Middleware } from 'bnbpay-sdk';
initBNBPay();
const app = express();
app.use(express.json());
// Register a paid API route
registerRoute({
routeId: 'premium-api',
networks: ['bnb'],
merchant: '0xYourMerchantAddress',
pricing: {
model: 'fixed',
amount: '0.05',
token: {
symbol: 'USDT',
address: '0x55d398326f99059fF775485246999027B3197955',
decimals: 18,
},
},
handler: async (ctx) => {
// Payment already verified when handler runs
return { data: 'Premium content', paidBy: ctx.payment.payer };
},
});
// Protect endpoint - returns 402 if not paid
app.post('/api/premium',
createX402Middleware({ routeId: 'premium-api' }),
(req, res) => res.json(req.x402Result)
);
app.listen(3000, () => console.log('Server running on :3000'));API Reference
Invoice API
import { invoiceApi } from 'bnbpay-sdk';
// Create invoice
const invoice = await invoiceApi.create({ ... });
// Get invoice
const invoice = await invoiceApi.get('inv_abc123');
// Get status
const { status, txHash } = await invoiceApi.getStatus('inv_abc123');
// Cancel invoice
await invoiceApi.cancel('inv_abc123');
// List invoices
const { data, hasMore } = await invoiceApi.list({ merchantId: '0x...', status: 'pending' });
// Wait for payment
const paidInvoice = await invoiceApi.waitForPayment('inv_abc123', { timeout: 60000 });
// Subscribe to updates (SSE)
const eventSource = invoiceApi.subscribe('inv_abc123');
// Get payment link
const link = invoiceApi.getPaymentLink('inv_abc123');Subscription API
import { subscriptionApi } from 'bnbpay-sdk';
// Plans
const plan = await subscriptionApi.createPlan({ ... });
const plan = await subscriptionApi.getPlan('plan_abc123');
const { data } = await subscriptionApi.listPlans({ merchantAddress: '0x...' });
// Subscriptions
const subscription = await subscriptionApi.subscribe({ planId: '...', subscriberAddress: '0x...' });
const subscription = await subscriptionApi.get('sub_abc123');
const { data } = await subscriptionApi.list({ status: 'active' });
// Manage subscriptions
await subscriptionApi.pause('sub_abc123');
await subscriptionApi.resume('sub_abc123');
await subscriptionApi.cancel('sub_abc123', true); // immediately
// Charges
const { data: charges } = await subscriptionApi.listCharges('sub_abc123');
await subscriptionApi.retryCharge('sub_abc123', 'charge_xyz');Payment API
import { paymentApi } from 'bnbpay-sdk';
// Get payment
const payment = await paymentApi.get('payment_abc123');
// Get status
const { status, payment } = await paymentApi.getStatus('payment_abc123');
// List payments
const { data } = await paymentApi.list({ payer: '0x...', network: 'bnb' });
// Check if can pay
const { canPay, reason } = await paymentApi.canPay({
network: 'bnb',
from: '0xPayer',
to: '0xMerchant',
token: '0xUSDT',
amount: '10000000000000000000',
});
// Build payment intent
const intent = await paymentApi.buildIntent({
mode: 'minimal',
network: 'bnb',
merchant: '0x...',
token: '0x...',
amount: '10.00',
scheme: 'permit2',
payer: '0x...',
invoiceId: 'inv_abc123',
});
// Relay payment
const result = await paymentApi.relay({ ... });
// Wait for confirmation
const payment = await paymentApi.waitForConfirmation('payment_abc123', { timeout: 120000 });Gasless Payments
import { gaslessApi, detectTokenCapabilities } from 'bnbpay-sdk';
import { ethers } from 'ethers';
// Detect token capabilities
const capabilities = await detectTokenCapabilities('0xUSDT...', provider);
console.log('Supports EIP-3009:', capabilities.supportsEIP3009);
console.log('Supports EIP-2612:', capabilities.supportsEIP2612);
console.log('Recommended scheme:', capabilities.recommendedScheme);
// Pay invoice gaslessly
const result = await gaslessApi.payInvoice({
merchantAddress: '0x...',
amount: '10.00',
paymentToken: 'USDT',
tokenAddress: '0x...',
invoiceId: 'inv_abc123',
network: 'bnb',
signer,
provider,
});
// Manual signing (advanced)
import { signPermit2WithWitness, signEIP2612, signEIP3009 } from 'bnbpay-sdk';
// Permit2 signature
const permit2Sig = await signPermit2WithWitness({ ... });
// EIP-2612 signature
const eip2612Sig = await signEIP2612({ ... });
// EIP-3009 signature
const eip3009Sig = await signEIP3009({ ... });Session API (x402)
import { sessionApi } from 'bnbpay-sdk';
// List sessions
const { data } = await sessionApi.list({ wallet: '0x...', role: 'payer' });
// Get session
const session = await sessionApi.get('session_abc123');
// Open session
const result = await sessionApi.open({ network: 'bnb', grant: { ... }, signature: '0x...' });
// Revoke session
await sessionApi.revoke({ network: 'bnb', sessionId: '...', deadline: ..., signature: '0x...' });
// Check budget
const { total, spent, remaining } = await sessionApi.getBudget('session_abc123');x402 Route Integration
Protect your API endpoints with x402 payment requirements. When a client hits a protected endpoint without payment, they receive a 402 Payment Required response with payment instructions.
Register a Route
import { registerRoute, x402Api } from 'bnbpay-sdk';
// Register an x402-protected route
registerRoute({
routeId: 'premium-api',
name: 'Premium Data API',
description: 'Access to premium market data',
networks: ['bnb', 'opbnb'],
merchant: '0xYourMerchantAddress',
pricing: {
model: 'fixed',
amount: '0.05', // 0.05 USDT per request
token: {
symbol: 'USDT',
address: '0x55d398326f99059fF775485246999027B3197955',
decimals: 18,
},
},
handler: async (ctx) => {
// ctx.payment contains verified payment info
console.log('Paid by:', ctx.payment.payer);
console.log('Amount:', ctx.payment.amount);
console.log('TX Hash:', ctx.payment.txHash);
// Your business logic
return { data: 'premium content', timestamp: Date.now() };
},
});Express.js Integration
import express from 'express';
import { createX402Middleware, createX402Handler, registerRoute } from 'bnbpay-sdk';
const app = express();
app.use(express.json());
// Register your route first (see above)
// Option 1: Middleware (passes result to next handler)
app.post('/api/premium',
createX402Middleware({ routeId: 'premium-api' }),
(req, res) => {
res.json(req.x402Result);
}
);
// Option 2: Standalone handler
app.post('/api/premium-v2', createX402Handler('premium-api'));
app.listen(3000);Dynamic Pricing
registerRoute({
routeId: 'analytics-api',
networks: ['bnb'],
merchant: '0xYourMerchantAddress',
pricing: {
model: 'dynamic',
calculate: async (input, network) => {
// Price based on data type
const prices = { basic: '0.01', advanced: '0.05', enterprise: '0.20' };
return {
amount: prices[input.dataType] || '0.01',
token: {
symbol: 'USDT',
address: '0x55d398326f99059fF775485246999027B3197955',
},
};
},
minAmount: '0.01',
maxAmount: '1.00',
},
handler: async (ctx) => {
return { analytics: `${ctx.input.dataType} data` };
},
});Lifecycle Hooks
registerRoute({
routeId: 'ai-api',
networks: ['bnb'],
merchant: '0xYourMerchantAddress',
pricing: { model: 'fixed', amount: '0.10', token: { ... } },
// Pre-payment validation
onBeforePayment: async (input, network) => {
if (!input.prompt) throw new Error('Prompt required');
},
// After payment verified
onPaymentVerified: async (ctx) => {
console.log('Payment verified:', ctx.payment.paymentId);
},
handler: async (ctx) => {
return { response: 'AI generated content' };
},
// After successful execution
onComplete: async (ctx, result) => {
console.log('Request completed:', ctx.executionId);
},
// Error handling
onError: async (ctx, error) => {
console.error('Request failed:', error.message);
},
});Programmatic Execution
import { executeRoute, buildRoutePaymentIntent, getPaymentRequirement } from 'bnbpay-sdk';
// Get payment requirement
const requirement = await getPaymentRequirement('premium-api', { query: 'test' }, 'bnb');
console.log('Price:', requirement.amount, requirement.token.symbol);
// Build payment intent for signing
const intent = await buildRoutePaymentIntent('premium-api', { query: 'test' }, '0xPayer...', 'bnb');
// Execute with payment
const result = await executeRoute({
routeId: 'premium-api',
network: 'bnb',
input: { query: 'test' },
payment: {
scheme: 'permit2',
payer: '0xPayer...',
permit2: { /* signed permit data */ },
witnessSignature: '0x...',
},
});
if (result.status === 'completed') {
console.log('Result:', result.result);
}Using the x402 API Object
import BNBPay from 'bnbpay-sdk';
// All x402 functions available via BNBPay.x402
BNBPay.x402.createRoute({ ... });
BNBPay.x402.execute({ ... });
BNBPay.x402.list(); // List all routes
BNBPay.x402.info('premium-api'); // Get route info
BNBPay.x402.configure({ debug: true }); // Configure managerUtilities
import {
formatAmount,
parseAmount,
shortenAddress,
generateQRCode,
buildPaymentURI,
} from 'bnbpay-sdk';
// Format amounts
formatAmount('1000000000000000000', 18); // "1.0"
parseAmount('10.5', 18); // "10500000000000000000"
// Format address
shortenAddress('0x1234567890abcdef1234567890abcdef12345678'); // "0x1234...5678"
// Generate QR code
const qrDataUrl = await generateQRCode('https://pay.bnbpay.org/invoice/inv_123');
// Build payment URI
const uri = buildPaymentURI({
merchant: '0x...',
amount: '10.00',
token: '0x...',
chainId: 56,
});
// "bnbpay:0x...?amount=10.00&token=0x...&chain=56"Supported Networks
| Network | Chain ID | Use Case | |---------|----------|----------| | BNB Chain | 56 | Production payments | | opBNB | 204 | Low-fee micropayments | | BNB Testnet | 97 | Development/testing |
Supported Tokens
BNB Chain (56)
- BNB - Native token
- USDT -
0x55d398326f99059fF775485246999027B3197955 - USDC -
0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d - FDUSD -
0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409
BNB Testnet (97)
- tBNB - Native token
- USDT -
0x337610d27c682E347C9cD60BD4b3b107C9d34dDd - USDC -
0x64544969ed7EBf5f083679233325356EbE738930
Gasless Payment Schemes
The SDK automatically detects and uses the best available scheme:
- EIP-3009 (TransferWithAuthorization) - Most efficient, direct transfer
- EIP-2612 (Permit) - Native token permits
- Permit2 (Universal) - Works with any ERC20 token
Configuration Options
initBNBPay({
// API base URL
apiUrl: 'https://api.bnbpay.org',
// Network mode: 'mainnet' | 'testnet'
networkMode: 'mainnet',
// Default network: 'bnb' | 'bnbTestnet' | 'opbnb'
defaultNetwork: 'bnb',
// Request timeout in ms
timeout: 30000,
// Retry attempts for failed requests
retryAttempts: 3,
// Custom RPC URLs
rpcUrls: {
bnb: 'https://your-rpc.com',
bnbTestnet: 'https://your-testnet-rpc.com',
},
// Contract addresses (auto-fetched if not provided)
contracts: {
registry: '0x...',
router: '0x...',
sessionStore: '0x...',
permit2: '0x...',
},
// Enable debug logging
debug: true,
});Error Handling
import { createInvoice } from 'bnbpay-sdk';
try {
const invoice = await createInvoice({ ... });
} catch (error) {
console.error('Failed to create invoice:', error.message);
}All API methods throw errors with descriptive messages. The SDK includes automatic retry logic with exponential backoff for transient failures.
TypeScript Support
The SDK is written in TypeScript and provides comprehensive type definitions:
import type {
// Core types
Invoice,
Subscription,
Payment,
NetworkKey,
PaymentScheme,
InvoiceStatus,
SubscriptionInterval,
// x402 Route types
X402RouteConfig,
X402RouteContext,
X402RouteResult,
X402PaymentRequired,
X402PaymentIntent,
PaymentVerification,
RouteTokenConfig,
X402RoutePricing,
} from 'bnbpay-sdk';Browser & Node.js Support
The SDK works in both environments:
// Browser
import { initBNBPay } from 'bnbpay-sdk';
// Node.js
import { initBNBPay } from 'bnbpay-sdk';
// Note: For SSE/WebSocket, ensure you have appropriate polyfillsContributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
