@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.jsFeatures
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 requestType 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.
