Addresses
ZK Privacy uses stealth addresses for receiving private transactions.
Address Format
zks1<bech32m_encoded_data>Example:
zks1qyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgp...Components
A ZK address encodes two public keys:
| Component | Size | Purpose |
|---|---|---|
| SPK | 33 bytes | Spending Public Key - your identity |
| VPK | 33 bytes | Viewing Public Key - for encryption |
zks1 + bech32m( SPK || VPK )
= zks1 + bech32m( 66 bytes )Getting Your Address
typescript
await client.connect({ ... });
const address = client.getAddress();
console.log(address); // zks1...The address is deterministic - same keys always produce the same address.
Sharing Your Address
Your ZK address is safe to share publicly. It's like a bank account number:
- ✅ Can receive deposits
- ✅ Can be posted on websites
- ❌ Cannot reveal your balance
- ❌ Cannot be used to track your transactions
Address Validation
typescript
import { decodeAddress } from '@zkprivacy/sdk';
try {
const { spk, vpk } = decodeAddress('zks1...');
console.log('Valid address');
} catch {
console.log('Invalid address');
}Generating New Addresses
For privacy, you might want separate addresses:
typescript
import { generateDepositAddress } from '@zkprivacy/sdk/shield';
// Generate fresh address
const { address, spendingKey } = generateDepositAddress();
// Save the spending key securely!
console.log('Address:', address);
console.log('Key:', spendingKey.toString(16));DANGER
If you lose the spending key, funds sent to that address are unrecoverable.
Address Derivation
Addresses are derived from the spending key:
spending_key (secret)
│
├──▶ SPK = spending_key * G
│
└──▶ viewing_key = hash(spending_key, "viewing")
│
└──▶ VPK = viewing_key * G
address = zks1 + bech32m(SPK || VPK)Multi-Account
Use account indices for multiple addresses from one mnemonic:
typescript
// First account (index 0)
await client.connect({
mode: 'standalone',
mnemonic: '...',
accountIndex: 0,
});
const addr0 = client.getAddress();
// Second account (index 1)
client.disconnect();
await client.connect({
mode: 'standalone',
mnemonic: '...',
accountIndex: 1,
});
const addr1 = client.getAddress();
// addr0 !== addr1QR Codes
Display addresses as QR codes for easy scanning:
typescript
import QRCode from 'qrcode';
const address = client.getAddress();
const qrDataUrl = await QRCode.toDataURL(address);
// Use in <img src={qrDataUrl} />