x402 Payments
Chain-agnostic micropayments for privacy services
Onyx integrates the x402 payment protocol to enable chain-agnostic micropayments for privacy services. Based on the HTTP 402 Payment Required status code, x402 allows users to pay for Solana privacy operations using assets on any of 15+ supported blockchain networks.
x402 revives the long-dormant HTTP 402 Payment Required status code as a machine-readable payment protocol:
- No accounts or API keys — payments are cryptographically authorized per-request
- Chain-agnostic — pay with USDC on Base, Polygon, Avalanche, Solana, or 11+ other networks
- Micropayments — perfect for pay-per-use privacy services ($0.01-0.02 per operation)
- Agent-native — AI agents can discover prices, construct payments, and access services autonomously
- Privacy-preserving — payment metadata separated from Solana privacy operations
Use cases:
- Pay for Solana relayer fees using USDC on any supported chain
- Cross-chain gas abstraction (future: use Polygon USDC to cover Solana SOL fees)
- Privacy-as-a-Service pricing for shield/transfer/unshield operations
- AI agent autonomous access to privacy infrastructure
Traditional payment systems create friction for privacy services:
Scenario: You want to use Onyx for private Solana transactions, but your treasury is on Base.
Traditional Approach:
- Bridge USDC from Base to Solana (slow, expensive, bridge risk)
- Convert USDC to SOL on a DEX (slippage, MEV exposure)
- Use SOL to pay for Onyx relayer fees
- Repeat for every privacy operation
Problems:
- High friction (3+ steps per payment)
- Expensive bridging fees ($5-20)
- Slow settlement (5-30 minutes)
- Forces users to hold multiple assets across chains
- AI agents can't autonomously manage cross-chain bridging
x402 Solution:
- Pay for privacy services directly with Base USDC
- Facilitator handles cross-chain settlement
- Access granted immediately
- Single-step, low-cost, agent-friendly
The x402 payment flow follows standard HTTP patterns with payment-specific headers:
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Client │ │ Server │ │ Facilitator │
└────┬─────┘ └────┬─────┘ └──────┬───────┘
│ │ │
│ 1. GET /resource │ │
│────────────────────────────>│ │
│ │ │
│ 2. 402 Payment Required │ │
│ X-Accept-Payment │ │
│<────────────────────────────│ │
│ │ │
│ 3. Parse requirements │ │
│ Construct payment │ │
│ Sign with EIP-712 │ │
│ │ │
│ 4. POST /verify │ │
│──────────────────────────────────────────────────────────────>│
│ │ │
│ │ 5. Validate signature │
│ │ Check balance │
│ │ Verify amount │
│ │ │
│ 6. Verification response │ │
│<──────────────────────────────────────────────────────────────│
│ │ │
│ 7. GET /resource │ │
│ X-PAYMENT (payload) │ │
│────────────────────────────>│ │
│ │ 8. POST /settle │
│ │───────────────────────────────>│
│ │ │
│ │ 9. Submit to blockchain │
│ │ Wait for confirmation │
│ │ │
│ │ 10. Settlement response │
│ │<───────────────────────────────│
│ 11. 200 OK + Resource │ │
│ X-PAYMENT-RESPONSE │ │
│<────────────────────────────│ │
│ │ │
Step-by-Step Breakdown
1. Initial Request Client requests a protected resource (e.g., privacy relayer submission endpoint).
2. Payment Required
Server responds with 402 Payment Required and X-Accept-Payment header containing:
- Price (e.g., "$0.01")
- Accepted networks (e.g., ["base", "polygon", "solana"])
- Merchant address
- Facilitator URL
3. Payment Construction Client parses requirements and constructs payment payload:
- Amount (in USDC atomic units, 6 decimals)
- Asset (USDC contract address for that network)
- Merchant (receiving address)
- Nonce (replay protection)
- Network identifier
4. Signature Client signs payment using:
- EVM chains: EIP-712 structured data signing
- Solana: Ed25519 signature on partially-signed transaction
5. Facilitator Verification Facilitator validates:
- Signature is cryptographically valid
- Payer has sufficient USDC balance
- Amount matches requirements
- Authorization is within time window (for EIP-3009)
- Nonce hasn't been used before
6. Verification Response Facilitator returns:
valid: true/falseverification_id: Unique identifier for this verificationpayment_id: On-chain transaction identifier (once settled)
7. Retry with Payment
Client retries original request with X-PAYMENT header containing signed payment payload.
8. Facilitator Settlement Server forwards payment to facilitator for on-chain settlement.
9. On-Chain Execution Facilitator submits transaction to blockchain and waits for confirmation.
10. Settlement Confirmation Facilitator confirms on-chain settlement with transaction hash.
11. Resource Access
Server grants access to resource with X-PAYMENT-RESPONSE header containing transaction details.
Onyx supports x402 payments on 15 blockchain networks (8 mainnets + 7 testnets):
Mainnet Networks
| Network | Chain ID | USDC Address | Scheme | Block Explorer |
|---|---|---|---|---|
| Base | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | eip3009 | basescan.org |
| Polygon | 137 | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 | eip3009 | polygonscan.com |
| Avalanche | 43114 | 0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E | eip3009 | snowtrace.io |
| Solana | — | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | solana-native | explorer.solana.com |
| IoTeX | 4689 | 0x3B2bf2b523f54C4E454F08Aa286D03115aFF326c | eip3009 | iotexscan.io |
| Peaq | 3338 | 0xfFfFFFffFFFfFFFF0000000000000000000000C1 | eip3009 | peaq.subscan.io |
| Sei | 1329 | 0x3894085Ef7Ff0f0aeDf52E2A2704928d1Ec074F1 | eip3009 | seitrace.com |
| XLayer | 196 | 0x74b7F16337b8972027F6196A17a631aC6dE26d22 | eip3009 | oklink.com/xlayer |
Testnet Networks
| Network | Chain ID | USDC Address | Scheme | Block Explorer |
|---|---|---|---|---|
| Base Sepolia | 84532 | 0x036CbD53842c5426634e7929541eC2318f3dCF7e | eip3009 | sepolia.basescan.org |
| Polygon Amoy | 80002 | 0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582 | eip3009 | amoy.polygonscan.com |
| Avalanche Fuji | 43113 | 0x5425890298aed601595a70AB815c96711a31Bc65 | eip3009 | testnet.snowtrace.io |
| Solana Devnet | — | 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU | solana-native | explorer.solana.com |
| Sei Testnet | 713715 | 0xdFb8434A90f86ED2b1d0548F826C2F49f70F655E | eip3009 | seitrace.com |
| XLayer Testnet | 195 | 0x9C3f01E4831e885F9Ee3C88d4C0b13c8f1f4d3F0 | eip3009 | oklink.com/xlayer-test |
Note: All networks use USDC as the payment token (6 decimals). EVM chains use the USDC contract address, while Solana uses the USDC SPL token mint address.
x402 supports two payment schemes depending on the blockchain:
EIP-3009 Scheme (EVM Chains)
EVM-compatible chains (Base, Polygon, Avalanche, etc.) use EIP-3009 TransferWithAuthorization with EIP-712 structured data signing.
Authorization Structure:
authorization = {
"from": "0xPAYER_ADDRESS", # Payer's wallet address
"to": "0xMERCHANT_ADDRESS", # Merchant's receiving address
"value": "10000", # Amount in USDC atomic units (6 decimals)
"validAfter": 0, # Unix timestamp (0 = valid immediately)
"validBefore": 1735689600, # Unix timestamp (expiration)
"nonce": "0x1234...abcd" # 32-byte hex (replay protection)
}EIP-712 Domain:
domain = {
"name": "USD Coin",
"version": "2",
"chainId": 8453, # Network-specific
"verifyingContract": "0x833589..." # USDC contract address
}Signature Generation Example:
from onyx.x402.signing import sign_eip712_payment
import secrets
import time
# Construct authorization
authorization = {
"from": wallet_address,
"to": merchant_address,
"value": str(int(0.01 * 1_000_000)), # $0.01 USDC = 10,000 atomic units
"validAfter": 0,
"validBefore": int(time.time()) + 3600, # Valid for 1 hour
"nonce": "0x" + secrets.token_hex(32) # Random 32-byte nonce
}
# Sign with EIP-712
signature = sign_eip712_payment(
authorization,
private_key=private_key,
network="base"
)
print(f"Signature: {signature}")
# Output: 0x1234...abcd (65 bytes: r + s + v)Security Properties:
- Cryptographic authorization: ECDSA signature proves ownership of private key
- Time-bounded:
validAfterandvalidBeforelimit authorization window - Replay protection: Each
noncecan only be used once on-chain - Scoped: Authorization specifies exact amount, recipient, and validity period
Solana Native Scheme
Solana uses partially-signed transactions with Ed25519 signatures.
Transaction Structure:
from solana.transaction import Transaction
from solana.system_program import TransferParams, transfer
from spl.token.instructions import transfer_checked, TransferCheckedParams
# Construct USDC SPL token transfer
transfer_ix = transfer_checked(
TransferCheckedParams(
program_id=TOKEN_PROGRAM_ID,
source=payer_usdc_account,
mint=USDC_MINT,
dest=merchant_usdc_account,
owner=payer_public_key,
amount=10_000, # 0.01 USDC (6 decimals)
decimals=6,
signers=[]
)
)
# Create partially-signed transaction
tx = Transaction()
tx.add(transfer_ix)
tx.recent_blockhash = (await client.get_recent_blockhash()).value.blockhash
tx.fee_payer = payer_public_key
tx.sign_partial(payer_keypair) # Payer signs, facilitator adds fee payer signature
# Serialize for transmission
payment_payload = tx.serialize()Security Properties:
- Ed25519 signatures: Curve25519-based cryptographic proof
- Recent blockhash: Serves as time-bound validity (blockhashes expire after ~60 seconds)
- Partial signing: Payer authorizes transfer, facilitator completes with fee payment
- On-chain validation: Solana runtime enforces signature and account ownership
Payment Scheme Comparison
| Feature | EIP-3009 (EVM) | Solana Native |
|---|---|---|
| Signature Algorithm | ECDSA (secp256k1) | Ed25519 (Curve25519) |
| Authorization Method | TransferWithAuthorization | Partially-signed Transaction |
| Nonce Format | 32-byte hex string | Recent blockhash |
| Time Window | validAfter / validBefore timestamps | Recent blockhash validity (~60s) |
| Gas Payment | Merchant pays gas for settlement | Facilitator pays rent/fees |
| Signature Size | 65 bytes (r + s + v) | 64 bytes (Ed25519 signature) |
The PayAI facilitator acts as a trusted intermediary for x402 payment verification and settlement. Onyx uses facilitator.payai.network by default.
Facilitator Role
The facilitator provides three core services:
1. Payment Verification (POST /verify)
- Validates cryptographic signatures (EIP-712 or Ed25519)
- Checks payer's USDC balance on the payment network
- Verifies amount meets merchant requirements
- Validates time windows and nonce uniqueness
- Returns
verification_idfor tracking
2. On-Chain Settlement (POST /settle)
- Submits transactions to blockchain
- Waits for confirmation (1-3 seconds typical)
- Returns transaction hash and settlement proof
- Handles gas fees (for EVM) or rent (for Solana)
3. Merchant Discovery (GET /list)
- Lists available merchants and their requirements
- Enables AI agents to discover pricing autonomously
- Returns accepted networks and payment terms
Verification Process
from onyx.x402.facilitator import FacilitatorClient
from onyx.x402.types import PaymentPayload, PaymentRequirements
facilitator = FacilitatorClient("https://facilitator.payai.network")
# Verify payment before settlement
verification = await facilitator.verify_payment(
payment_payload=payment_payload,
requirements=payment_requirements
)
if verification.valid:
print(f"Payment verified: {verification.verification_id}")
print(f"Ready for settlement")
else:
print(f"Payment invalid: {verification.error}")Validation Checks:
- ✅ Signature matches payer address
- ✅ Amount ≥ required price
- ✅ USDC balance ≥ payment amount
- ✅ Network is supported
- ✅ Authorization is within time window (EIP-3009)
- ✅ Nonce hasn't been used (replay protection)
Settlement Flow
# Settlement (only after successful verification)
settlement = await facilitator.settle_payment(
payment_payload=payment_payload,
verification_id=verification.verification_id
)
print(f"Transaction hash: {settlement.tx_hash}")
print(f"Confirmed: {settlement.confirmed}")
print(f"Block: {settlement.block_number}")Settlement Steps:
- Facilitator receives settlement request
- Constructs on-chain transaction (EIP-3009 call or Solana transfer)
- Submits to blockchain
- Waits for confirmation (1-3 seconds typical)
- Returns transaction hash and settlement proof
Error Handling
The facilitator returns structured errors:
| Error Code | Meaning | Resolution |
|---|---|---|
INVALID_SIGNATURE | Signature doesn't match payer | Check private key and authorization structure |
INSUFFICIENT_BALANCE | Payer lacks USDC | Fund payer address with USDC |
AMOUNT_TOO_LOW | Payment below required price | Increase payment amount |
EXPIRED_AUTHORIZATION | Outside validAfter/validBefore window | Regenerate with fresh timestamps |
NONCE_ALREADY_USED | Replay attack detected | Generate new nonce |
NETWORK_NOT_SUPPORTED | Network not in accepted list | Choose different network |
x402 payments integrate seamlessly with Onyx privacy operations:
Integration with Privacy Operations
from onyx import OnyxClient
from onyx.x402 import X402Client
# Initialize clients
privacy = OnyxClient()
x402 = X402Client(
network="polygon", # Pay with Polygon USDC
wallet_address="0xYOUR_ADDRESS",
private_key="0xYOUR_KEY"
)
# Pay for relayer access using Polygon USDC
payment_response = await x402.pay_for_access(
resource_url="https://relayer.onyx-sdk.com/submit",
price_usd=0.02, # $0.02 for relayer fee
merchant_address="0xRELAYER_ADDRESS"
)
print(f"Payment confirmed: {payment_response.tx_hash}")
print(f"Access token: {payment_response.access_token}")
# Use access token for private Solana transfer
tx = await privacy.private_transfer_async(
recipient=recipient_key,
amount=1_000_000_000, # 1 SOL (in lamports)
access_token=payment_response.access_token # Authorizes relayer submission
)
print(f"Private transfer submitted: {tx.signature}")Use Cases
1. Privacy-as-a-Service Pay for individual privacy operations (shield, transfer, unshield) with per-operation pricing.
2. Relayer Fee Payment Pay relayer fees using USDC on any supported network instead of SOL on Solana.
3. Cross-Chain Gas Abstraction (Future: Q1-Q2 2026) Execute Solana privacy operations without holding SOL — pay all fees with USDC on Base, Polygon, etc.
4. AI Agent Autonomous Access AI agents discover prices, construct payments, and access privacy services without human intervention.
x402 uses USDC (6 decimals) for all payments.
USD to Atomic Units Conversion
def usd_to_atomic(usd_amount: float) -> int:
"""Convert USD to USDC atomic units (6 decimals)"""
return int(usd_amount * 1_000_000)
# Examples
shield_fee = usd_to_atomic(0.01) # 10,000 atomic units
transfer_fee = usd_to_atomic(0.02) # 20,000 atomic units
unshield_fee = usd_to_atomic(0.01) # 10,000 atomic unitsTypical Pricing
| Operation | Price (USD) | Atomic Units | Description |
|---|---|---|---|
| Shield | $0.01 | 10,000 | Deposit assets into privacy pool |
| Private Transfer | $0.02 | 20,000 | Anonymous transfer within pool |
| Unshield | $0.01 | 10,000 | Withdraw from privacy pool |
| Relayer Fee | $0.005 | 5,000 | IP privacy and transaction submission |
Network Fee Comparison
Paying for a $0.02 private transfer:
| Method | Total Cost | Breakdown | Time |
|---|---|---|---|
| x402 (Base) | ~$0.021 | 0.001 Base gas | 1-2s |
| x402 (Polygon) | ~$0.020 | 0.0001 Polygon gas | 1-2s |
| x402 (Solana) | ~$0.020 | 0.00001 Solana fee | 1-2s |
| Traditional (bridge from Base) | ~$8.02 | 8 bridge fee | 5-30min |
Gas abstraction savings: x402 reduces friction by 400x compared to traditional bridging.
What x402 Guarantees
✅ Cryptographic Authorization
- Payments are signed with EIP-712 (EVM) or Ed25519 (Solana)
- Only the private key holder can authorize payments
- Signatures are validated both off-chain (facilitator) and on-chain (settlement)
✅ Nonce-Based Replay Protection
- Each payment uses a unique nonce (EIP-3009) or recent blockhash (Solana)
- Once a payment is settled, the nonce is consumed on-chain
- Replaying the same signature fails on-chain validation
✅ Time-Bounded Authorizations
- EIP-3009 payments specify
validAfterandvalidBeforetimestamps - Facilitator rejects expired authorizations before settlement
- Prevents stale authorizations from being settled later
✅ Facilitator Verification Before Settlement
- Payment validity is checked before on-chain submission
- Reduces risk of failed transactions and wasted gas
- Provides fast feedback (under 100ms) on payment issues
✅ Atomic Settlement
- On-chain settlement is atomic (either fully succeeds or fully reverts)
- No partial payments or stuck funds
- Transaction hash provides cryptographic proof of settlement
What Users Control
🔑 Payment Authorization
- Users sign payments with their private keys
- No delegation to third parties
- Each payment is explicitly authorized
💰 Amount and Recipient
- Authorization specifies exact USDC amount
- Merchant address is signed in authorization
- Cannot be modified without invalidating signature
🌐 Network Selection
- Users choose which blockchain to pay on
- Can select based on gas fees, balance, or convenience
- Supports seamless switching between networks
What Facilitators Cannot Do
❌ Steal Funds
- Facilitator cannot move funds without user signature
- Signatures are validated on-chain before transfer
- EIP-3009/Solana enforce cryptographic authorization
❌ Modify Payment Amounts
- Signed authorization locks the amount
- Changing the amount invalidates the signature
- On-chain validation would reject modified payments
❌ Change Merchant Addresses
- Merchant address is part of the signed authorization
- Modifying it breaks the signature
- Funds can only go to the authorized merchant
❌ Replay Old Payments
- Nonces (EIP-3009) or blockhashes (Solana) prevent replay
- Once settled, the nonce is consumed on-chain
- Subsequent attempts with the same nonce fail
Facilitator Trust Assumptions
The x402 trust model treats the facilitator as semi-trusted:
What Facilitators Can See:
- Payment amounts
- Payer addresses
- Merchant addresses
- Payment networks
- Timing information
What Facilitators Can Do:
- Delay settlement (DoS attack)
- Refuse to settle valid payments (censorship)
- Log payment metadata
- Correlate payments across merchants
What Facilitators Cannot Do:
- Steal user funds (requires signature)
- Modify payment amounts (invalidates signature)
- Settle to different merchants (invalidates signature)
- Replay settled payments (nonce consumed on-chain)
Mitigations
1. Multiple Facilitators
- Users can configure alternative facilitators
- Competition prevents censorship and poor service
- Onyx SDK supports custom facilitator URLs
2. Self-Hosted Facilitators
- Users can run their own facilitator instance
- Eliminates reliance on third-party services
- Full control over verification and settlement
3. On-Chain Verification Fallback
- Users can submit EIP-3009 transactions directly on-chain
- Bypasses facilitator entirely
- Higher gas costs, but trustless
4. Signature-Based Authorization
- On-chain contracts enforce cryptographic validation
- Facilitator cannot forge valid signatures
- Users retain ultimate control
Privacy vs. Convenience Trade-offs
| Aspect | x402 Payments | Solana Privacy Operations |
|---|---|---|
| Transaction Amounts | Visible to facilitator | Hidden by zkSNARKs |
| Payer/Merchant | Visible to facilitator | Anonymous within pool |
| Network Metadata | Visible (payment network) | Obfuscated (if using relayer) |
| IP Privacy | Standard HTTPS | Requires relayer for full privacy |
Best Practice: Combine x402 with relayers for maximum privacy. Pay for relayer access using x402, then submit private transfers through the relayer for complete IP + transaction privacy.
What x402 Payments Reveal
⚠️ Payment Amounts
- USDC amount is visible in the authorization
- Facilitator sees exact payment values
- On-chain observers can see settlement amounts
⚠️ Payer Address
- Payment authorization includes
fromaddress (payer) - Facilitator knows who is paying
- On-chain settlement links address to merchant
⚠️ Merchant Address
- Payment authorization includes
toaddress (merchant) - Reveals which service the user is accessing
- Can leak information about user activities (e.g., "user paid relayer → likely doing private transfer")
⚠️ Payment Network
- Network choice reveals user's blockchain holdings
- Patterns of network usage can be analyzed
- Timing correlations possible
⚠️ Timing Information
- Payment timestamps visible to facilitator
- Can correlate payment time with Solana transaction time
- Timing analysis may link payments to on-chain activity
What Remains Private
✅ Solana Privacy Operations
- zkSNARK proofs hide transaction amounts
- Commitments obscure sender and recipient
- Nullifiers prevent linking without revealing identity
- Merkle tree membership proofs hide which UTXO is spent
✅ Private Transfer Details
- Transfer amounts within Solana privacy pool are hidden
- Recipients are encrypted (only they can decrypt)
- Sender anonymity within the pool
✅ Relayer-Protected IP Addresses
- If using relayers, IP address is not visible to Solana RPC
- Relayer breaks link between IP and on-chain activity
- Payment for relayer via x402 doesn't expose IP to relayer (HTTPS only)
Privacy Best Practices
1. Use Different Addresses
# Bad: Same address for payments and privacy operations
payment_address = "0xALICE"
privacy_address = "0xALICE" # Same!
# Good: Separate addresses
payment_address = "0xALICE_PAYMENTS" # For x402 payments
privacy_address = "0xALICE_PRIVACY" # For Solana privacy operations2. Combine with Relayers
# Pay for relayer access using x402
payment = await x402.pay_for_access(
resource_url="https://relayer.onyx-sdk.com/submit",
price_usd=0.02
)
# Submit private transfer through relayer (IP privacy)
tx = await privacy.private_transfer_async(
recipient=recipient_key,
amount=1_000_000_000,
relayer_url="https://relayer.onyx-sdk.com",
access_token=payment.access_token
)3. Vary Payment Timing
- Avoid paying immediately before privacy operations
- Add random delays to decorrelate timing
- Batch payments for multiple operations
4. Use Privacy-Friendly Networks
- Prefer networks with high transaction volume (harder to isolate your payment)
- Rotate between networks to avoid patterns
- Consider gas costs vs. privacy trade-offs
Choosing the optimal payment network balances fees, speed, and available balance.
Selection Factors
1. Gas Fees
- Base: ~$0.001 per transaction
- Polygon: ~$0.0001 per transaction
- Avalanche: ~$0.002 per transaction
- Solana: ~$0.00001 per transaction
2. Settlement Speed
- Base: ~2 seconds
- Polygon: ~2 seconds
- Avalanche: ~2 seconds
- Solana: ~1 second
3. Available Balance
- Check USDC balance on each network
- Prefer networks where you already hold USDC
- Avoid unnecessary bridging
4. Network Reliability
- Check network status and uptime
- Prefer networks with consistent block times
- Avoid congested networks during high-load periods
Network Selection Example
from onyx.x402 import X402Client
from onyx.x402.networks import get_mainnet_networks, get_network_config
def select_optimal_network(
supported_networks: list[str],
user_balances: dict[str, float],
min_balance_usd: float = 0.02
) -> str:
"""
Select optimal network for x402 payment
Args:
supported_networks: Networks accepted by merchant
user_balances: User's USDC balance on each network (in USD)
min_balance_usd: Minimum balance required for payment
Returns:
Network identifier (e.g., "polygon")
Raises:
ValueError: If no suitable network found
"""
# Filter networks with sufficient balance
viable_networks = [
net for net in supported_networks
if user_balances.get(net, 0) >= min_balance_usd
]
if not viable_networks:
raise ValueError(
f"Insufficient balance on any supported network. "
f"Need at least ${min_balance_usd} USDC."
)
# Rank by estimated gas fees (lower is better)
gas_fees = {
"solana": 0.00001,
"polygon": 0.0001,
"base": 0.001,
"avalanche": 0.002,
"iotex": 0.0005,
"peaq": 0.001,
"sei": 0.001,
"xlayer": 0.0005,
}
# Select network with lowest fees
return min(viable_networks, key=lambda net: gas_fees.get(net, 0.001))
# Usage
user_balances = {
"base": 10.50, # $10.50 USDC on Base
"polygon": 5.25, # $5.25 USDC on Polygon
"solana": 0.01, # $0.01 USDC on Solana (insufficient)
}
optimal_network = select_optimal_network(
supported_networks=["base", "polygon", "solana"],
user_balances=user_balances,
min_balance_usd=0.02 # Need $0.02 for private transfer
)
print(f"Selected network: {optimal_network}")
# Output: "polygon" (sufficient balance + lowest fees among viable options)Example 1: Pay for Privacy Shield Operation
from onyx import OnyxClient
from onyx.x402 import X402Client
async def shield_with_x402_payment():
"""Shield SOL using x402 payment for relayer fee"""
# Initialize clients
privacy = OnyxClient()
x402 = X402Client(
network="base-sepolia", # Testnet for demo
wallet_address="0xYOUR_ADDRESS",
private_key="0xYOUR_PRIVATE_KEY"
)
# Pay for relayer access using Base Sepolia USDC
print("Paying for relayer access...")
payment = await x402.pay_for_access(
resource_url="https://relayer-testnet.onyx-sdk.com/submit",
price_usd=0.01, # $0.01 shield fee
merchant_address="0xRELAYER_ADDRESS"
)
print(f"✓ Payment confirmed: {payment.tx_hash}")
print(f"✓ Access token: {payment.access_token}")
# Shield 1 SOL into privacy pool
print("Shielding 1 SOL...")
shield_tx = await privacy.shield_async(
amount=1_000_000_000, # 1 SOL (9 decimals)
access_token=payment.access_token
)
print(f"✓ Shield complete: {shield_tx.signature}")
print(f"✓ Commitment: {shield_tx.commitment}")
return shield_tx
# Run
import asyncio
asyncio.run(shield_with_x402_payment())Example 2: Cross-Chain Gas Abstraction
from onyx import OnyxClient
from onyx.x402 import X402Client
async def pay_solana_fees_with_polygon():
"""
Pay for Solana privacy operations using Polygon USDC
Demonstrates cross-chain gas abstraction
"""
privacy = OnyxClient()
x402 = X402Client(
network="polygon", # Pay with Polygon USDC
wallet_address="0xYOUR_POLYGON_ADDRESS",
private_key="0xYOUR_POLYGON_KEY"
)
# Pay relayer fee using Polygon USDC
print("Paying relayer fee with Polygon USDC...")
payment = await x402.pay_for_access(
resource_url="https://relayer.onyx-sdk.com/submit",
price_usd=0.02, # $0.02 for private transfer
merchant_address="0xRELAYER_ADDRESS"
)
print(f"✓ Paid ${0.02} USDC on Polygon")
print(f"✓ Transaction: {payment.tx_hash}")
# Execute private transfer on Solana (without holding SOL)
print("Executing private transfer on Solana...")
transfer_tx = await privacy.private_transfer_async(
recipient="RECIPIENT_PUBLIC_KEY",
amount=500_000_000, # 0.5 SOL
access_token=payment.access_token
)
print(f"✓ Private transfer complete: {transfer_tx.signature}")
print(f"✓ No SOL holdings required!")
return transfer_tx
# Run
import asyncio
asyncio.run(pay_solana_fees_with_polygon())Example 3: AI Agent Autonomous Payment
from onyx.x402 import X402Client
from onyx.x402.types import PaymentRequirements
import httpx
async def ai_agent_autonomous_access():
"""
AI agent discovers merchant requirements and pays autonomously
No human intervention required
"""
# Step 1: Agent discovers resource and pricing
async with httpx.AsyncClient() as http:
response = await http.get("https://api.onyx-sdk.com/privacy/shield")
if response.status_code == 402:
print("✓ Resource requires payment (402 Payment Required)")
# Parse payment requirements
requirements = PaymentRequirements.from_headers(response.headers)
print(f"✓ Price: {requirements.price}")
print(f"✓ Accepted networks: {requirements.networks}")
print(f"✓ Merchant: {requirements.merchant}")
# Step 2: Agent selects optimal network (has Base USDC)
selected_network = "base"
print(f"✓ Selected network: {selected_network}")
# Step 3: Agent constructs and signs payment
x402 = X402Client(
network=selected_network,
wallet_address="0xAGENT_ADDRESS",
private_key="0xAGENT_PRIVATE_KEY"
)
payment = await x402.pay_for_access(
resource_url="https://api.onyx-sdk.com/privacy/shield",
price_usd=float(requirements.price.replace("$", "")),
merchant_address=requirements.merchant
)
print(f"✓ Payment signed and verified")
print(f"✓ Settlement tx: {payment.tx_hash}")
# Step 4: Agent accesses resource with payment proof
async with httpx.AsyncClient() as http:
response = await http.get(
"https://api.onyx-sdk.com/privacy/shield",
headers={"X-PAYMENT": payment.access_token}
)
if response.status_code == 200:
print(f"✓ Access granted!")
data = response.json()
print(f"✓ Resource: {data}")
return data
# Run
import asyncio
asyncio.run(ai_agent_autonomous_access())Production Ready (Now)
✅ 15+ blockchain networks supported
- 8 mainnets: Base, Polygon, Avalanche, Solana, IoTeX, Peaq, Sei, XLayer
- 7 testnets for development and testing
✅ Dual payment schemes
- EIP-3009 for EVM chains (Base, Polygon, Avalanche, etc.)
- Solana native for Solana mainnet/devnet
✅ PayAI facilitator integration
- Verification, settlement, and merchant discovery
- Sub-second payment verification
- 1-3 second settlement confirmation
✅ Python SDK
X402Clientfor payment construction and signing- Async/sync support
- Full type hints and documentation
✅ Relayer fee payments
- Pay for IP privacy with any supported network
- Seamless integration with
OnyxClient
Future Enhancements (Q1-Q2 2026)
🚀 Full Gas Abstraction
- Pay all Solana fees (rent, transaction fees, compute units) with USDC on any chain
- AI agents operate without holding SOL
- Seamless cross-chain UX
🚀 Additional Networks
- Arbitrum, Optimism, and other major L2s
- Emerging EVM chains as they gain USDC support
🚀 Payment Channels
- Frequent micropayments without per-transaction settlement
- Lightning-style payment channels for high-volume users
- Instant payments with periodic on-chain settlement
🚀 Multi-Token Support
- Support for stablecoins beyond USDC (USDT, DAI)
- Native token payments (ETH, MATIC, AVAX)
- Automatic conversion and settlement
🚀 Privacy-Preserving Payment Metadata
- Blind signatures for merchant-unlinkable payments
- Zero-knowledge proofs of payment (without revealing amounts)
- Enhanced privacy for payment correlations
| Payment Method | Setup Complexity | Privacy | Cost per Payment | Settlement Speed | Agent-Friendly |
|---|---|---|---|---|---|
| x402 | None | Medium | Low (~$0.001 gas) | Fast (1-3s) | ✅ Excellent |
| API Keys | Account signup | Low (account linked) | Medium (subscription) | Instant | ⚠️ Requires registration |
| Direct On-Chain | Wallet setup | High (pseudonymous) | High ($5-20 bridge fees) | Slow (5-30min) | ⚠️ Complex bridging |
| Payment Channels | Channel setup | Medium | Very Low (amortized) | Instant | ❌ Complex setup/teardown |
Why x402 is ideal for privacy services:
- Zero setup: No accounts or pre-funding required
- Pay-per-use: Perfect for micropayments ($0.01-0.02 per operation)
- Chain-agnostic: Use existing holdings on any of 15+ networks
- Agent-native: Machine-readable pricing and autonomous payment construction
- Balanced privacy: Payment metadata separate from Solana privacy operations
- Relayers — IP privacy and gas abstraction layer for Solana privacy operations
- Privacy Model — Overall privacy guarantees and anonymity properties
- zkSNARKs — Zero-knowledge proof system underlying Onyx privacy
- Note Encryption — ECDH-based recipient discovery for private transfers
- API Reference:
- X402Client API — Technical API documentation for payment construction
- OnyxClient API — Privacy operations with x402 integration
- External Resources:
- PayAI Documentation — Full x402 protocol specification
- EIP-3009 Specification — TransferWithAuthorization standard
- HTTP 402 Status Code — Payment Required definition
