@exe-pay/privacy

Privacy features for confidential transactions on Solana, including stealth addresses, view keys, payment proofs, and more.

All Features Production-Ready on Mainnet

All privacy features have been tested and deployed to Solana mainnet. Ready for production use.

Installation

npm install @exe-pay/privacy @solana/web3.js

Features

1. Stealth Addresses

Monero-inspired one-time addresses that protect recipient privacy. Uses X25519 ECDH + Keccak-256 hashing.

import { generateStealthAddress, deriveStealthAddress } from '@exe-pay/privacy';
import { Keypair } from '@solana/web3.js';

// Generate stealth meta-address (receiver does this once)
const wallet = Keypair.generate();
const metaAddress = await generateStealthMetaAddress(wallet);
console.log('Share this meta-address:', metaAddress);

// Send payment (sender does this)
const { stealthAddress, ephemeralPubkey, viewTag } = 
  await generateStealthAddress(metaAddress);

// Now send SOL to stealthAddress
// Include ephemeralPubkey and viewTag in transaction memo

// Scan for payments (receiver does this)
const payments = await scanForPayments(
  connection,
  wallet.publicKey,
  wallet.secretKey
);

2. View Keys

Read-only keys for compliance and auditing. Derived using SHA-256 from Ed25519 spending keys.

import { generateViewKeys, encodeViewKeys } from '@exe-pay/privacy';

// Generate view keys
const message = new TextEncoder().encode('Generate View Keys');
const signature = await signMessage(message);
const viewKeys = await generateViewKeys(publicKey, signature);

// Encode for export
const encoded = encodeViewKeys(viewKeys);
console.log('Private View Key:', encoded.privateViewKey); // Keep secret
console.log('Public View Key:', encoded.publicViewKey);   // Share with auditors
console.log('Spend Public Key:', encoded.spendPublicKey); // Your wallet address

// Export for accounting software
const credential = {
  publicViewKey: encoded.publicViewKey,
  spendPublicKey: encoded.spendPublicKey,
  network: 'mainnet-beta'
};

3. Payment Proofs

Cryptographic proofs to prove payment was made to a specific recipient.

import { generatePaymentProof, verifyPaymentProof } from '@exe-pay/privacy';

// Generate proof (sender)
const proof = await generatePaymentProof({
  senderPrivateKey: sender.secretKey,
  recipientPublicKey: recipient.publicKey,
  amount: 1000000,
  transactionSignature: txSignature
});

// Verify proof (anyone can verify)
const isValid = await verifyPaymentProof(proof, {
  recipientPublicKey: recipient.publicKey,
  amount: 1000000,
  transactionSignature: txSignature
});

4. Integrated Addresses

Stealth addresses with embedded payment IDs for invoice tracking.

import { generateIntegratedAddress, decodeIntegratedAddress } from '@exe-pay/privacy';

// Generate with payment ID
const paymentId = 'INV-12345';
const integratedAddress = await generateIntegratedAddress(
  metaAddress,
  paymentId
);

// Decode to get payment ID
const { stealthAddress, paymentId: decoded } = 
  await decodeIntegratedAddress(integratedAddress);

console.log('Payment ID:', decoded); // 'INV-12345'

5. Subaddresses

Generate multiple unlinkable receiving addresses from a single wallet.

import { generateSubaddress } from '@exe-pay/privacy';

// Generate subaddresses
const subaddress1 = await generateSubaddress(wallet, 0, 1); // Account 0, Index 1
const subaddress2 = await generateSubaddress(wallet, 0, 2); // Account 0, Index 2

// Use for different purposes
const businessAddress = await generateSubaddress(wallet, 0, 100);
const personalAddress = await generateSubaddress(wallet, 0, 200);

6. Enhanced Scanning with View Tags

99% faster payment detection using one-byte view tags.

import { scanForPayments } from '@exe-pay/privacy';

// Scan with view tags (optimized)
const payments = await scanForPayments(
  connection,
  publicKey,
  privateKey,
  {
    useViewTags: true,      // Enable fast scanning
    limit: 100,             // Last 100 transactions
    onProgress: (found) => {
      console.log(`Found ${found} payments`);
    }
  }
);

// Each payment includes:
payments.forEach(payment => {
  console.log('Amount:', payment.amount);
  console.log('Stealth Address:', payment.stealthAddress);
  console.log('Ephemeral Pubkey:', payment.ephemeralPubkey);
  console.log('View Tag:', payment.viewTag);
});

7. RPC Privacy

Hide IP address by rotating through multiple RPC endpoints.

import { PrivacyRPCClient } from '@exe-pay/privacy';

// Create client with multiple endpoints
const rpcClient = new PrivacyRPCClient([
  'https://api.mainnet-beta.solana.com',
  'https://solana-api.projectserum.com',
  'https://rpc.ankr.com/solana',
]);

// Use like normal Connection
const balance = await rpcClient.getBalance(publicKey);
const latestBlockhash = await rpcClient.getLatestBlockhash();

// Rotates endpoints automatically for each request

Type Definitions

interface StealthAddress {
  stealthAddress: PublicKey;
  ephemeralPubkey: PublicKey;
  viewTag: number;
}

interface ViewKey {
  privateViewKey: Uint8Array;
  publicViewKey: PublicKey;
  spendPublicKey: PublicKey;
}

interface EncodedViewKey {
  privateViewKey: string;  // Base58 encoded
  publicViewKey: string;   // Base58 encoded
  spendPublicKey: string;  // Base58 encoded
}

interface PaymentProof {
  senderPublicKey: PublicKey;
  recipientPublicKey: PublicKey;
  amount: number;
  transactionSignature: string;
  proof: Uint8Array;
}

interface ScannedPayment {
  amount: number;
  stealthAddress: PublicKey;
  ephemeralPubkey: PublicKey;
  viewTag: number;
  transactionSignature: string;
  timestamp: number;
}

Security Notes

⚠️ Important Security Information

  • View Keys: Private view keys reveal transaction history but cannot spend funds. Keep them secure like financial statements.
  • Stealth Addresses: Each payment uses a unique address. Never reuse the same stealth address.
  • Key Storage: Never expose private keys or view keys in client-side code. Use secure storage.
  • RPC Privacy: While RPC rotation helps, consider using a VPN for maximum privacy.

Best Practices

  • Always use view tags for scanning - 99% performance improvement
  • Generate view keys once and store securely for compliance
  • Use integrated addresses for business invoices and order tracking
  • Create subaddresses for different purposes (business, personal, savings)
  • Keep ephemeral keys in transaction memos for recipient scanning
  • Rotate RPC endpoints when sending sensitive transactions

Mainnet Configuration

import { Connection } from '@solana/web3.js';
import { PrivacyRPCClient } from '@exe-pay/privacy';

// For mainnet production
const connection = new PrivacyRPCClient([
  'https://api.mainnet-beta.solana.com',
  'https://solana-api.projectserum.com',
], {
  commitment: 'confirmed',
  confirmTransactionInitialTimeout: 60000
});

// All privacy features work on mainnet
const stealthAddress = await generateStealthAddress(metaAddress);
const viewKeys = await generateViewKeys(publicKey, signature);

💡 Need Help?

Check out our code examples for complete working implementations, or visit our GitHub repository for more resources.