Skip to content

PRXVT/sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@prxvt/sdk

px402 - Private x402 payments using zero-knowledge proofs. Pay privately without revealing your identity or transaction history.

npm version License: MIT

Features

  • Full Privacy: Each payment uses a fresh burner wallet, unlinkable to previous payments
  • x402 Compatible: Works seamlessly with any x402-enabled API
  • Cross-Chain: Deposit on one chain, spend on another (Base <-> Polygon)
  • ZK Proofs: All transactions validated with Groth16 zero-knowledge proofs
  • Note Encryption: AES-256-GCM encryption for secure note storage

Installation

npm install @prxvt/sdk

Quick Start

1. Initialize SDK

import { PrivacySDK } from '@prxvt/sdk';

const sdk = new PrivacySDK({
  chain: 'base', // or 'polygon'
});

2. Deposit USDC -> Get Private Note

// Deposit 10 USDC -> Get private note
const note = await sdk.deposit(10, '0xYourPrivateKey');

// The note is your private balance - save it securely!
console.log('Note created:', JSON.stringify(note));

3. Make Private px402 Payments

// Load your note
sdk.setNote(note);

// Wrap fetch with privacy
const privateFetch = sdk.wrapFetch(fetch);

// Make px402 payment - COMPLETELY PRIVATE!
const response = await privateFetch('https://api.example.com/x402/endpoint', {
  method: 'POST',
  body: JSON.stringify({ message: 'Hello!' }),
});

// Get updated note (old note is spent, this is the change!)
const updatedNote = sdk.getUpdatedNote();

4. Encrypt Notes for Storage

import { encryptNote, decryptNote } from '@prxvt/sdk';

// Encrypt note with password
const encrypted = await encryptNote(note, 'my-secret-password');
localStorage.setItem('encrypted-note', encrypted);

// Later: decrypt to use
const decrypted = await decryptNote(encrypted, 'my-secret-password');

Complete Example

import {
  PrivacySDK,
  encryptNote,
  decryptNote,
  getNoteBalance,
  logger
} from '@prxvt/sdk';

async function main() {
  // Enable debug logging (optional)
  logger.setLevel('debug');

  // 1. Setup SDK
  const sdk = new PrivacySDK({ chain: 'base' });

  // 2. Deposit USDC
  const note = await sdk.deposit(10, '0xYourPrivateKey');
  console.log('Deposited:', getNoteBalance(note), 'USDC');

  // 3. Encrypt and save
  const encrypted = await encryptNote(note, 'password123');
  localStorage.setItem('note', encrypted);

  // 4. Make payments
  sdk.setNote(note);
  const privateFetch = sdk.wrapFetch(fetch);

  const response = await privateFetch('https://api.example.com/x402');
  console.log('Payment successful!');

  // 5. Save updated note
  const updated = sdk.getUpdatedNote();
  const newEncrypted = await encryptNote(updated, 'password123');
  localStorage.setItem('note', newEncrypted);

  console.log('Remaining:', getNoteBalance(updated), 'USDC');
}

API Reference

PrivacySDK

The main SDK class for privacy payments.

Constructor

new PrivacySDK(config: PrivacySDKConfig)

Config Options:

Option Type Default Description
chain 'base' | 'polygon' 'base' Blockchain to use
bundlerUrl string prxvt proxy Custom bundler URL
bundlerApiKey string - Pimlico API key (optional)
rpcUrl string public RPC Custom RPC URL

Methods

deposit(amount: number, privateKey: string): Promise<Note>

Deposit USDC to create a private note.

const note = await sdk.deposit(50, '0xYourPrivateKey');
depositFast(amount: number, privateKey: string): Promise<Note>

Fast deposit using ERC-3009 transferWithAuthorization (gasless).

const note = await sdk.depositFast(50, '0xYourPrivateKey');
makePayment(note: Note, recipient: string, amount: number): Promise<PaymentResult>

Make a direct payment to a recipient.

const result = await sdk.makePayment(note, '0x742d35Cc...', 1.5);
console.log('TX:', result.txHash);
console.log('Change note:', result.note);
wrapFetch(fetch: typeof fetch): typeof fetch

Wrap fetch to automatically handle x402 payments.

const privateFetch = sdk.wrapFetch(fetch);
const response = await privateFetch('https://api.example.com/x402');
setNote(note: Note): void

Load a saved note into the SDK.

sdk.setNote(savedNote);
getUpdatedNote(): Note | undefined

Get the current note state after payments.

const updatedNote = sdk.getUpdatedNote();

Encryption Functions

encryptNote(note: Note, password: string): Promise<string>

Encrypt a note with AES-256-GCM.

const encrypted = await encryptNote(note, 'my-password');
// encrypted is a base64 string safe for storage
decryptNote(encrypted: string, password: string): Promise<Note>

Decrypt an encrypted note.

const note = await decryptNote(encrypted, 'my-password');
isEncryptedNote(str: string): boolean

Check if a string is an encrypted note.

if (isEncryptedNote(stored)) {
  const note = await decryptNote(stored, password);
}

Helper Functions

getNoteBalance(note: Note): number

Get balance from a note in USDC.

const balance = getNoteBalance(note); // e.g., 10.5
hasEnoughBalance(note: Note, amount: number): boolean

Check if note has sufficient balance.

if (!hasEnoughBalance(note, 5)) {
  console.log('Insufficient balance');
}
formatUSDCAmount(microUsdc: number): string

Format micro USDC to display string.

formatUSDCAmount(1500000); // "1.50"
parseUSDCAmount(usdc: number): number

Parse USDC to micro USDC.

parseUSDCAmount(1.5); // 1500000

Cross-Chain Functions

isCrossChain(depositChain: string, paymentChain: string): boolean

Check if payment is cross-chain.

isCrossChain('base', 'polygon'); // true
isCrossChain('base', 'base');    // false
getChainEid(chain: string): number

Get LayerZero endpoint ID for a chain.

getChainEid('base');    // 30184
getChainEid('polygon'); // 30109

Logger

logger.setLevel(level: LogLevel): void

Configure logging level.

import { logger } from '@prxvt/sdk';

logger.setLevel('debug'); // 'none' | 'error' | 'warn' | 'info' | 'debug'

Error Types

import {
  PrivacySDKError,
  InsufficientBalanceError,
  InvalidNoteError,
  DecryptionError,
  MerkleProofError,
  ProofGenerationError,
  BundlerError,
  NetworkError,
  PaymentRequiredError,
  TransactionError,
  NullifierSpentError,
} from '@prxvt/sdk';

Types

Note

interface Note {
  version: string;
  commitments: NoteCommitment[];
}

interface NoteCommitment {
  secret: string;      // Random secret (field element)
  nullifier: string;   // Random nullifier (field element)
  amount: number;      // Amount in micro USDC (6 decimals)
  depositChain: string; // Chain where commitment was created
}

PaymentResult

interface PaymentResult {
  note: Note;              // Updated note with change
  txHash: string;          // Transaction hash
  nullifierHash: string;   // Nullifier hash (for tracking)
  burnerAddress?: string;  // Burner wallet address
  burnerPrivateKey?: string; // Burner private key (for x402)
}

PrivacySDKConfig

interface PrivacySDKConfig {
  chain?: 'base' | 'polygon';
  bundlerUrl?: string;
  bundlerApiKey?: string;
  rpcUrl?: string;
  attestorUrl?: string;
  circuitWasmPath?: string;
  circuitZkeyPath?: string;
}

How It Works

Privacy Payment Flow

  1. Generate Burner Wallet: SDK creates ephemeral EOA
  2. ZK Proof Generation: Proves you have a valid note without revealing it
  3. Withdraw to Burner: UserOperation withdraws USDC to burner (paymaster sponsors gas!)
  4. Sign x402 Payment: Burner signs EIP-3009 authorization (no gas needed!)
  5. Make API Call: Payment is sent to merchant
  6. Create Change Note: Remaining balance becomes a new note
  7. Discard Burner: Burner wallet is thrown away

Result: Completely private payment, no gas fees, untraceable!

Cross-Chain Payments

Deposit on Base, pay on Polygon (or vice versa):

// Deposit on Base
const sdk = new PrivacySDK({ chain: 'base' });
const note = await sdk.deposit(10, privateKey);

// Pay on Polygon
const polygonSdk = new PrivacySDK({ chain: 'polygon' });
polygonSdk.setNote(note); // Note from Base works on Polygon!
const result = await polygonSdk.makePayment(note, recipient, 1);

Cross-chain payments use an attestor service that verifies the nullifier hasn't been spent on the origin chain.

Browser Usage

For browser environments, load Poseidon hash and snarkjs:

<script src="https://cdn.prxvt.io/poseidon-browser.js"></script>
<script src="https://cdn.jsdelivr.net/npm/snarkjs@0.7.0/build/snarkjs.min.js"></script>
<script type="module">
  import { PrivacySDK } from '@prxvt/sdk';

  const sdk = new PrivacySDK({ chain: 'base' });
  // ... use SDK
</script>

Node.js Usage

For Node.js, install circomlibjs:

npm install circomlibjs snarkjs
import { PrivacySDK } from '@prxvt/sdk';
import { buildPoseidon } from 'circomlibjs';
import * as snarkjs from 'snarkjs';

// Setup global Poseidon (required for Node.js)
const poseidon = await buildPoseidon();
globalThis.window = {
  poseidonHash3: (a, b, c) => Promise.resolve(
    poseidon.F.toString(poseidon([BigInt(a), BigInt(b), BigInt(c)]))
  ),
  poseidonHash2: (a, b) => Promise.resolve(
    poseidon.F.toString(poseidon([BigInt(a), BigInt(b)]))
  ),
  poseidonHash: (a) => Promise.resolve(
    poseidon.F.toString(poseidon([BigInt(a)]))
  ),
  snarkjs,
};

const sdk = new PrivacySDK({ chain: 'base' });

Important Notes

Note Management

  • Notes are spent after each payment: You CANNOT reuse the same note
  • Always save the updated note: After each payment, get and save the new note
  • UTXO model: Each payment consumes the old commitment and creates a new change commitment

Privacy Guarantees

  • Unlinkable payments: Each payment uses a fresh burner wallet
  • No transaction history: Payments cannot be linked together
  • Zero-knowledge proofs: Your identity and note are never revealed
  • Cross-chain privacy: Deposit and withdraw on different chains

Security

  • Never share your note data: Notes contain secrets that prove ownership
  • Use note encryption: Always encrypt notes before storage
  • HTTPS only: Always use HTTPS for API calls
  • Trusted RPCs: Use trusted RPC providers

Supported Chains

Chain Network USDC Contract LayerZero EID
Base Mainnet 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 30184
Polygon Mainnet 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 30109

License

MIT

Links

About

Privacy SDK for x402 payments

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published