Skip to content

Shield Module

Lightweight utilities for deposits. Import from @zkprivacy/sdk/shield for a smaller bundle (~150KB).

typescript
import { shieldTo, encryptNoteForRecipient, generateDepositAddress } from '@zkprivacy/sdk/shield';

shieldTo

Shield tokens to a ZK address.

typescript
await shieldTo(
  config: ShieldConfig,
  params: ShieldParams
): Promise<ShieldResult>

ShieldConfig

PropertyTypeDescription
rpcUrlstringEthereum RPC endpoint
poolAddressAddressPool contract address

ShieldParams

PropertyTypeRequiredDescription
recipientstringYesZK address (zks1...)
amountstringYesHuman-readable amount
tokenAddressAddressNoToken address (omit for ETH)
walletClientWalletClientYesViem wallet client

ShieldResult

PropertyTypeDescription
txHashHashTransaction hash
commitmentbigintNote commitment

Example

typescript
import { shieldTo, DEPLOYMENTS } from '@zkprivacy/sdk/shield';

const result = await shieldTo(
  {
    rpcUrl: DEPLOYMENTS.remote.rpcUrl,
    poolAddress: DEPLOYMENTS.remote.pool,
  },
  {
    recipient: 'zks1...',
    amount: '100',
    tokenAddress: DEPLOYMENTS.remote.tokens.zkUSD,
    walletClient,
  }
);

console.log('TX:', result.txHash);

encryptNoteForRecipient

Create encrypted note data for a recipient.

typescript
encryptNoteForRecipient(
  recipient: string,    // zks1... address
  amount: bigint,
  tokenId: bigint,
): { encryptedNote: `0x${string}`, commitment: bigint }

Parameters

ParameterTypeDescription
recipientstringZK address (zks1...)
amountbigintAmount in smallest units
tokenIdbigintToken ID (0n for ETH)

Returns

PropertyTypeDescription
encryptedNote0x${string}Hex-encoded encrypted note
commitmentbigintNote commitment for Merkle tree

Example

typescript
import { encryptNoteForRecipient } from '@zkprivacy/sdk/shield';
import { parseUnits } from 'viem';

const { encryptedNote, commitment } = encryptNoteForRecipient(
  'zks1...',
  parseUnits('100', 6),  // 100 USDC
  BigInt(tokenAddress),
);

// Use in direct shield call
await walletClient.writeContract({
  address: tokenAddress,
  abi: EMT_ABI,
  functionName: 'shield',
  args: [
    amount,
    `0x${commitment.toString(16).padStart(64, '0')}`,
    encryptedNote,
  ],
});

Important

Always pass tokenId. Omitting it creates invalid commitments that can't be spent.


generateDepositAddress

Create a new ZK address for receiving deposits.

typescript
generateDepositAddress(): {
  address: string;
  spendingKey: bigint;
}

Returns

PropertyTypeDescription
addressstringZK address (zks1...)
spendingKeybigintPrivate key to spend funds

Example

typescript
import { generateDepositAddress } from '@zkprivacy/sdk/shield';

const deposit = generateDepositAddress();

console.log('Send funds to:', deposit.address);
console.log('SAVE THIS KEY:', deposit.spendingKey.toString(16));

// Later, use the key to access funds
await client.connect({
  mode: 'standalone',
  spendingKey: deposit.spendingKey,
});

Security

The spending key controls all funds. Store it securely!


Address Utilities

decodeAddress

Decode a ZK address into its components.

typescript
import { decodeAddress } from '@zkprivacy/sdk';

const { spk, vpk } = decodeAddress('zks1...');

encodeAddress

Encode components into a ZK address.

typescript
import { encodeAddress } from '@zkprivacy/sdk';

const address = encodeAddress(spk, vpk);
// Returns: zks1...

Bundle Size

The shield module is designed for minimal bundle size:

ModuleSizeDependencies
@zkprivacy/sdk/shield~150KB@noble/curves, poseidon
@zkprivacy/sdk~2MB+ NoirJS, bb.js WASM

Use the shield module for:

  • Deposit pages
  • Payment links
  • Widgets
  • Server-side scripts

Use the full SDK when you need:

  • Balance checking
  • Transfers
  • Unshields

Released under the MIT License.