@perkos/service-pricing
v1.0.1
Published
Dynamic pricing service with strategy patterns for x402 payment protocol
Maintainers
Readme
@perkos/service-pricing
Dynamic pricing service with strategy patterns for x402 payment protocol. Provides vendor-centric pricing with multiple strategy types for flexible monetization.
Installation
npm install @perkos/service-pricingUsage
import {
createPricingStrategy,
FixedPricingStrategy,
TieredPricingStrategy,
UsageBasedPricingStrategy,
TimeBucketPricingStrategy,
usdToAtomicUnits,
atomicUnitsToUsd,
formatPrice,
type PricingContext,
type VendorPricingConfig,
type PriceResult
} from '@perkos/service-pricing';
// Create a fixed pricing strategy
const config: VendorPricingConfig = {
id: 'config-1',
vendorId: 'vendor-1',
strategyType: 'fixed',
name: 'Standard Pricing',
isDefault: true,
priority: 1,
enabled: true,
parameters: {
type: 'fixed',
price: '1000000', // $1.00 USDC (6 decimals)
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
network: 'base'
},
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
const strategy = createPricingStrategy(config);
// Calculate price
const context: PricingContext = {
request: {
method: 'POST',
path: '/api/generate',
headers: {},
query: {}
},
vendor: {
id: 'vendor-1',
name: 'My Service',
walletAddress: '0x...',
network: 'base',
chainId: 8453,
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
basePriceUsd: '1.00',
pricingConfig: config
},
endpoint: {
id: 'endpoint-1',
path: '/api/generate',
method: 'POST',
priceUsd: '1.00'
},
timestamp: Date.now()
};
const result = await strategy.calculatePrice(context);
// => { amount: '1000000', asset: '0x...', network: 'base', ... }Pricing Strategies
Fixed Pricing
Static price per request.
const config = {
strategyType: 'fixed',
parameters: {
type: 'fixed',
price: '1000000', // $1.00 USDC
asset: '0x...',
network: 'base'
}
};Tiered Pricing
Volume-based pricing with discounts.
const config = {
strategyType: 'tiered',
parameters: {
type: 'tiered',
tiers: [
{ name: 'Starter', upTo: 100, pricePerRequest: '1000000' },
{ name: 'Growth', upTo: 1000, pricePerRequest: '800000', discount: 20 },
{ name: 'Enterprise', upTo: -1, pricePerRequest: '500000', discount: 50 }
],
asset: '0x...',
network: 'base',
resetPeriod: 2592000 // 30 days
}
};Usage-Based Pricing
Pay per unit (token, byte, time).
const config = {
strategyType: 'usage-based',
parameters: {
type: 'usage-based',
pricePerUnit: '100', // $0.0001 per unit
unit: 'per-token',
minimumCharge: '100000', // $0.10 minimum
maximumCharge: '10000000', // $10.00 maximum
asset: '0x...',
network: 'base'
}
};Time-Bucket Pricing
Peak/off-peak pricing based on time of day.
const config = {
strategyType: 'time-bucket',
parameters: {
type: 'time-bucket',
basePrice: '1000000',
peakMultiplier: 1.5,
offPeakMultiplier: 0.7,
peakHours: [
{ start: 9, end: 12 },
{ start: 14, end: 18 }
],
timezone: 'America/New_York',
asset: '0x...',
network: 'base'
}
};Utility Functions
Currency Conversion
import { usdToAtomicUnits, atomicUnitsToUsd, formatPrice } from '@perkos/service-pricing';
// Convert USD string to atomic units (USDC 6 decimals)
const atomic = usdToAtomicUnits('1.50'); // => '1500000'
// Convert atomic units back to USD
const usd = atomicUnitsToUsd('1500000'); // => '1.500000'
// Format for display
const display = formatPrice(1500000n, '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913');
// => { formatted: '1.500000', symbol: 'USDC', decimals: 6 }Discount & Multiplier
import { applyDiscount, applyMultiplier } from '@perkos/service-pricing';
// Apply 20% discount
const discounted = applyDiscount(1000000n, 20); // => 800000n
// Apply 1.5x multiplier
const multiplied = applyMultiplier(1000000n, 1.5); // => 1500000nTime Bucket Detection
import { getTimeBucket } from '@perkos/service-pricing';
const bucket = getTimeBucket('America/New_York', [
{ start: 9, end: 12 },
{ start: 14, end: 18 }
]);
// => 'peak' | 'off-peak' | 'normal'Types
PricingStrategyType
type PricingStrategyType =
| 'fixed'
| 'tiered'
| 'usage-based'
| 'time-bucket'
| 'auction'
| 'subscription'
| 'custom';PricingUnit
type PricingUnit =
| 'per-request'
| 'per-token'
| 'per-byte'
| 'per-second'
| 'per-minute'
| 'per-hour'
| 'per-day'
| 'per-month';PriceResult
interface PriceResult {
amount: string; // Price in atomic units
asset: Address; // Token contract address
network: string; // Network name
breakdown?: PriceBreakdown[];
validUntil?: number; // Unix timestamp
minAmount?: string;
display?: PriceDisplay;
cacheKey?: string;
}PricingContext
interface PricingContext {
request: RequestContext;
user?: UserContext;
vendor: VendorContext;
endpoint: EndpointContext;
environment?: EnvironmentContext;
timestamp: number;
}Supported Assets
The service includes built-in symbol mapping for common assets:
| Network | Asset | Symbol | |---------|-------|--------| | Base | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | USDC | | Base Sepolia | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | USDC | | Ethereum | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 | USDC | | Polygon | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 | USDC | | Arbitrum | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 | USDC | | Optimism | 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 | USDC | | Avalanche | 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E | USDC |
Strategy Factory
Use the factory function to create strategies from configuration:
import { createPricingStrategy } from '@perkos/service-pricing';
const strategy = createPricingStrategy(config);
// Validate configuration
const validation = strategy.validate();
if (!validation.valid) {
console.error('Invalid config:', validation.errors);
}
// Generate cache key
const cacheKey = strategy.generateCacheKey(context);
// Calculate price
const result = await strategy.calculatePrice(context);Related Packages
- @perkos/types-x402 - Core x402 types
- @perkos/service-x402 - x402 service orchestrator
License
MIT
