Skip to content

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:

ComponentSizePurpose
SPK33 bytesSpending Public Key - your identity
VPK33 bytesViewing 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 !== addr1

QR 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} />

Released under the MIT License.