Skip to main content

API Reference

Complete API reference for the Privacy Boost TypeScript SDK.

Generated Documentation

Full API documentation can be generated using TypeDoc:
# From packages/privacy-boost-ts directory
npm run docs

# Documentation will be generated in docs/api/
The generated docs include:
  • All exported types and interfaces
  • JSDoc comments and examples
  • Type signatures and inheritance

PrivacyBoost

Main SDK class.

PrivacyBoost.create(config)

Creates and initializes a new SDK instance.
static async create(config: PrivacyBoostConfig): Promise<PrivacyBoost>
Parameters:
NameTypeDescription
config.appIdstringApplication identifier
config.serverUrlstringPrivacy Boost server URL
config.chainIdnumber(Optional) EVM chain ID (auto-discovered from server)
config.shieldContractAddressstring(Optional) Shield contract address (auto-discovered from server)
config.wethContractAddressstring(Optional) WETH contract address
Example:
const sdk = await PrivacyBoost.create({
  appId: 'your-app-id',
  serverUrl: 'https://optimism.sepolia.privacyboost.io',
  wethContractAddress: "0x4200000000000000000000000000000000000006"
});

sdk.auth

Authentication resource.

auth.authenticate(adapter, options?)

Connect a wallet, derive privacy keys, and authenticate with the server in a single call.
async authenticate(
  adapter: WalletAdapter,
  options?: AuthenticateOptions
): Promise<AuthResult>

interface AuthenticateOptions {
  keySource?: KeySource;
  tokenProvider?: (payload: LoginPayload) => Promise<{ token: string; expiresIn: number }>;
}
Parameters:
NameTypeDescription
adapterWalletAdapterWallet adapter implementation
optionsAuthenticateOptions(Optional) Options object with keySource and tokenProvider
options.keySourceKeySource(Optional) Key derivation source. Defaults to walletDerived when no persistence is configured.
options.tokenProviderfunction(Optional) Callback to obtain a JWT from the login payload
Returns: AuthResult - either { status: 'authenticated', privacyAddress, mpk } or { status: 'credentialRequired', action, unlockType, submit }. If credential is required, call result.submit(credential) to complete authentication.

auth.logout()

End session completely, clear all state.
async logout(): Promise<void>

auth.clearSession()

Clear JWT only, keep keys for quick re-auth.
async clearSession(): Promise<void>

auth.isConnected()

Check if wallet is connected.
isConnected(): boolean

auth.isAuthenticated()

Check if user is authenticated.
isAuthenticated(): boolean

auth.getPrivacyAddress()

Get user’s privacy address.
getPrivacyAddress(): string | null

auth.getMpk()

Get user’s master public key.
getMpk(): string | null

sdk.vault

Vault resource for privacy operations.

vault.shield(params)

Deposit tokens to private balance.
async shield(params: ShieldParams): Promise<ShieldResult>

interface ShieldParams {
  tokenAddress: Hex;
  amount: bigint;
  /** Defaults to the caller's own MPK. Set to shield directly to another user. */
  recipientMpk?: bigint;
  onProgress?: OnProgress;
}

interface ShieldResult {
  /** Hash of the shield transaction submitted to the chain. */
  txHash: Hex;
  /** Note commitment registered in the shielded pool. */
  commitment: Hex;
  /** Fee charged for this shield, in token wei. Not surfaced by the shield response, so usually undefined; query `vault.getFees()` for the schedule. */
  fee?: bigint;
  /** On-chain shield request ID, from the `ShieldRequested` event. */
  requestId: string;
  /** Set only when ETH was wrapped to WETH as part of the flow. */
  wrapTxHash?: Hex;
}

vault.unshield(params)

Withdraw tokens to public address.
async unshield(params: UnshieldParams): Promise<UnshieldResult>

interface UnshieldParams {
  tokenAddress: Hex;
  amount: bigint;
  recipientAddress: Hex;
  onProgress?: OnProgress;
  /**
   * When true and the token is WETH, automatically wait for the unshield to
   * land on-chain and then unwrap the received WETH back to native ETH.
   * Requires `wethContractAddress` to be configured. Reports
   * `UnshieldStep.unwrapping` via `onProgress`.
   */
  unwrapWeth?: boolean;
}

interface UnshieldResult {
  /** Server-side request ID for this unshield. Use to track status. */
  requestId: string;
  /**
   * Local placeholder hash used to track pending status until the canonical
   * on-chain hash is available. Not the final on-chain transaction hash.
   */
  txHash: Hex;
  /** Amount unshielded, in token wei. */
  amount: bigint;
}

vault.send(params)

Send private transfer.
async send(params: SendParams): Promise<TransactionResult>

interface SendParams {
  to: PrivacyAddress;
  tokenAddress: Hex;
  amount: bigint;
}

interface TransactionResult {
  /** Server-side request ID for this transfer. Use to track status. */
  requestId: string;
  /**
   * Local placeholder hash used to track pending status until the canonical
   * on-chain hash is available. Not the final on-chain transaction hash.
   */
  txHash: Hex;
}

vault.prepareShield(params)

Build a deposit payload without submitting it — for callers that relay the transaction themselves (a gasless relayer, an EIP-7702 session key, or a plain eth_sendRawTransaction). Returns the calldata to relay plus the note commitment; nothing is sent on-chain and no wallet is used. After relaying, call the top-level finalizeShield with the mined receipt to recover the on-chain request id. recipient shields to another privacy address; omit it to shield to yourself.
async prepareShield(params: PrepareShieldParams): Promise<PreparedShield>

interface PrepareShieldParams {
  tokenAddress: Hex;
  amount: bigint;
  /** Recipient privacy address. Omit to shield to yourself. */
  recipient?: PrivacyAddress;
}

interface PreparedShield {
  /** ERC-20 approve(pool, amount). Omitted when allowance is managed out of band. */
  approve?: ShieldCall;
  /** WETH deposit() wrap. Present only when shielding native ETH. */
  wrap?: ShieldCall;
  /** The requestDeposit(...) call. */
  shield: ShieldCall;
  /** Note commitment to track; also appears on-chain inside the shield call. */
  commitment: string;
  finalize: { shieldContract: string; tokenId: number };
}

/** A single on-chain call to relay. `value` and `data` are 0x-hex. */
interface ShieldCall {
  to: string;
  value: string;
  data: string;
}

vault.getBalance(tokenAddress)

Get the cached balance entry for a token. Reads from the local store and may fetch from the server on a cache miss. To force a network refresh, call vault.refreshBalance(tokenAddress) first.
async getBalance(tokenAddress: string): Promise<TokenBalance>

vault.getAllBalances()

Get all token balances.
async getAllBalances(): Promise<TokenBalance[]>

interface TokenBalance {
  tokenAddress: Hex;
  /** Private balance held in the shielded pool, in token wei. */
  shieldedBalance: bigint;
  /** Public balance in the connected wallet, in token wei. */
  walletBalance: bigint;
  symbol?: string;
  decimals?: number;
  /** Number of unspent notes contributing to `shieldedBalance`. */
  noteCount?: number;
}

vault.refreshBalance(tokenAddress)

Refresh a single token balance from the server.
async refreshBalance(tokenAddress: Hex): Promise<void>

vault.refreshBalances()

Refresh all tracked balances from the server.
async refreshBalances(): Promise<void>

vault.getToken(address)

Get token metadata for a single token.
async getToken(address: string): Promise<TokenMetadata>

interface TokenMetadata {
  address: Hex;
  symbol: string;
  decimals: number;
  name: string;
  priceUSD?: number;
  /** Minimum shield amount enforced by the protocol, in token wei (string). */
  minShieldAmount?: string;
}

vault.getTokens()

Get metadata for every token registered with the protocol.
async getTokens(): Promise<TokenMetadata[]>

parseAmount(amount, decimals)

Parse a human-readable amount to a bigint. Exported as a standalone utility from the SDK package.
import { parseAmount } from '@sunnyside-io/privacy-boost';

parseAmount(amount: string, decimals: number): bigint

formatAmount(amount, decimals)

Format a bigint amount as a human-readable string. Exported as a standalone utility from the SDK package.
import { formatAmount } from '@sunnyside-io/privacy-boost';

formatAmount(amount: bigint, decimals: number): string

Stateless shield helpers

Top-level functions for building a deposit payload without a signed-in session — for a backend that holds only a recipient’s privacy address. No wallet, no private keys. Imported from the package root.

buildShieldPayload(params)

Build a recipient-targeted deposit payload from public material only. Resolve tokenId, shieldContractAddress, and teePublicKey from the token catalog / config. An ephemeral sender keypair is generated and discarded internally, and the note is spendable only by recipient.
import { buildShieldPayload } from '@sunnyside-io/privacy-boost';

async function buildShieldPayload(params: BuildShieldPayloadParams): Promise<PreparedShield>

interface BuildShieldPayloadParams {
  tokenAddress: Hex;
  amount: bigint;
  /** Recipient privacy address (required). */
  recipient: PrivacyAddress;
  /** Resolved on-chain token id (from the token catalog). */
  tokenId: number;
  shieldContractAddress: Hex;
  /** Required only when shielding native ETH. */
  wethContractAddress?: Hex;
  teePublicKey: string;
  /** Per-token minimum in raw units (token catalog `minShieldAmount`); rejects below it. */
  minShieldAmount?: bigint;
  /** Emit the ERC-20 approve call. Defaults to `true`. */
  emitApprove?: boolean;
}

finalizeShield(params)

Recover the on-chain shield request id from the mined receipt of a relayed deposit (see vault.prepareShield). Stateless — the caller obtained the receipt from its own relay/RPC, so no signed-in session is needed. Throws if the deposit reverted or the DepositRequested log is absent.
import { finalizeShield } from '@sunnyside-io/privacy-boost';

async function finalizeShield(params: FinalizeShieldParams): Promise<ShieldResult>

interface FinalizeShieldParams {
  /** Mined transaction receipt (viem/ethers shape). */
  receipt: unknown;
  /** Shield pool contract — the DepositRequested emitter (from `PreparedShield.finalize`). */
  shieldContract: Hex;
  /** Commitment from the `PreparedShield` being settled. */
  commitment: Hex;
}

sdk.transactions

Transactions resource.

transactions.fetchHistory(params?)

Get transaction history.
async fetchHistory(params?: TransactionHistoryParams): Promise<Transaction[]>

interface TransactionHistoryParams {
  type?: TransactionType;
  tokenAddress?: string;
  limit?: number;
}

interface Transaction {
  txHash: Hex;
  type: TransactionType;
  direction: TransactionDirection;
  status: TransactionStatus;
  tokenAddress?: Hex;
  amount?: bigint;
  receivers: ReceiverTransfer[];
  createdAt: number;
  updatedAt: number;
  to?: Hex;
  from?: Hex;
  tokenSymbol?: string;
  commitment?: Hex;
  complianceStatus?: ComplianceStatus;
  error?: string;
}

enum TransactionType {
  shield = 'shield',
  unshield = 'unshield',
  transfer = 'transfer',
}

enum TransactionDirection {
  incoming = 'incoming',
  outgoing = 'outgoing',
}

enum TransactionStatus {
  pending = 'pending',
  /** Submitted on-chain, not yet finalized. */
  preconfirmed = 'preconfirmed',
  completed = 'completed',
  failed = 'failed',
  /** Blocked by compliance. See `complianceStatus`. */
  blocked = 'blocked',
}

sdk.portal

Hidden-recipient portal deposit addresses. Preview feature — pending external audit.

portal.create(opts?)

Derive a portal address E, delegate it, register the owner binding, and publish the discovery entry — in one call.
async create(opts?: CreatePortalOptions): Promise<Portal>

portal.list()

async list(): Promise<PortalInfo[]>

portal.deposits(address)

async deposits(address: string): Promise<PortalDeposit[]>

portal.status(address)

async status(address: string): Promise<PortalStatus>
Launch limitation: delegated always reports false.

portal.sweep(address, tokenId)

Self-service sweep backstop (operator-run at launch). Returns the tx hash.
async sweep(address: string, tokenId: number): Promise<string>

portal.reclaim(depositId)

Reclaim an un-credited deposit after the cancel delay; funds return to E. Returns the tx hash.
async reclaim(depositId: string): Promise<string>

portal.withdraw(params)

Build a signed raw EIP-1559 tx that withdraws funds resting at E (escape hatch). Broadcast it yourself.
withdraw(params: WithdrawPortalParams): string

portal.delegateAddress()

The portal delegate address from /info, or undefined if unsupported.
delegateAddress(): string | undefined
See the portal guide for the Portal, PortalInfo, PortalStatus, PortalDeposit, PortalDepositState, CreatePortalOptions, and WithdrawPortalParams types.

Gift Methods (sdk.wasm)

Claimable transfers. Preview feature — exposed on the underlying WASM SDK via sdk.wasm. Each fund/claim/refund returns a TransferResult (extended with optional giftRecord and claimLink).
MethodDescription
giftFundToWallet(params)Fund a gift bound to a wallet (no privacy address)
giftFund(params)Fund a gift bound to a wallet, sealed to a privacy address
giftClaim(params)Claim a pending gift by index
giftClaimByCGift(params)Claim by stable commitment cGift
giftClaimFromLink(params)Claim directly from a pbgift:v1:... link
giftRefundByRecord(index)Refund an unclaimed gift via a saved record
giftRefund(params)Refund by supplying every gift field manually
getPendingGifts()List claimable gifts addressed to the wallet
getGiftRecords()Local records of gifts you funded (for refunds)
decodeGiftLink(link)Decode + decrypt a claim link offline into a preview
giftFundSecretBearer(params) also exists but is experimental, disabled by default, and a bearer instrument — see the concept page. Full parameter shapes and the GiftRecord / PendingGift / GiftLinkPreview types are in the gift guide.

Utility Functions

isValidPrivacyAddress(address)

Check if address is valid privacy address.
function isValidPrivacyAddress(address: string): boolean

validatePrivacyAddress(address)

Validate a privacy address.
function validatePrivacyAddress(address: string): { valid: boolean; message: string }

encodePrivacyAddress(mpk, viewingPublicKey)

Encode MPK and viewing public key to privacy address.
function encodePrivacyAddress(mpk: bigint, viewingPublicKey: Point): PrivacyAddress

decodePrivacyAddress(address)

Decode privacy address to components.
function decodePrivacyAddress(address: PrivacyAddress): {
  mpk: bigint;
  viewingPublicKey: Point;
}

extractMpkFromPrivacyAddress(address)

Extract MPK from privacy address.
function extractMpkFromPrivacyAddress(address: PrivacyAddress): Hex

isEvmAddress(address)

Check if valid EVM address.
function isEvmAddress(address: string): boolean

isNativeEth(address)

Check if address represents native ETH.
function isNativeEth(address: Hex): boolean

Types

KeySource

Key derivation source, passed to authenticate().
type KeySource =
  | { type: 'walletDerived' }
  | { type: 'mnemonic'; phrase: string }
  | { type: 'rawSeed'; hexSeed: string };
VariantDescription
walletDerivedDerive keys from a wallet signature (default when no persistence is configured)
mnemonicDerive keys from a BIP-39 mnemonic phrase
rawSeedDerive keys from a raw 32-byte hex seed

Hex

type Hex = `0x${string}`

PrivacyAddress

type PrivacyAddress = string // 96-byte payload, 194 chars including `0x` prefix
The payload encodes the master public key (32 bytes) and the viewing public key X/Y (32 bytes each). Hex-encoded, that is 192 characters; including the 0x prefix the string is 194 characters.

WalletAdapter

interface WalletAdapter {
  connect(): Promise<{ address: string; chainId: number }>;
  disconnect(): Promise<void>;
  signMessage(message: string): Promise<string>;
  /** `typedDataJson` is a JSON-stringified EIP-712 typed-data payload. */
  signTypedData(typedDataJson: string): Promise<string>;
  sendTransaction(tx: unknown): Promise<string>;
  getAddress(): Promise<string>;
  getChainId(): Promise<number>;
}

OnProgress

type OnProgress = (progress: {
  step: ShieldStep | UnshieldStep;
  message: string;
  txHash?: Hex;
}) => void

enum ShieldStep {
  wrapping = 'wrapping',     // Wrapping ETH to WETH
  approving = 'approving',   // Approving token spend
  shielding = 'shielding',   // Submitting the shield transaction
  compliance = 'compliance', // Awaiting compliance check
}

enum UnshieldStep {
  preparing = 'preparing',     // Fetching notes and proofs
  proving = 'proving',         // Generating the ZK proof
  unshielding = 'unshielding', // Submitting the unshield transaction
  unwrapping = 'unwrapping',   // Unwrapping WETH back to ETH (only if `unwrapWeth: true`)
}

FeeRates

Fee schedule applied to vault operations.
interface FeeRates {
  /** Flat fee added to private transfers, in token wei (string). Defaults to "0". */
  transferFeeFlat: string;
  /** Fee deducted from unshields, in basis points (1 bp = 0.01%). */
  unshieldFeeBps: number;
  /** Whether the user pays the fee or the application sponsors it. */
  feeModel?: 'user_pays' | 'app_pays';
}
When feeModel is 'app_pays', the fee is settled out of band by the application — users see the gross amount. Shield fee schedules are available from vault.getFees(); the shield response does not currently surface the actual charged fee.

ComplianceStatus

type ComplianceStatus = 'PENDING' | 'LEGIT' | 'ILLICIT';
StatusMeaning
PENDINGCompliance check is in progress; the deposit cannot be spent yet.
LEGITCleared; funds are usable.
ILLICITRejected by compliance; funds are quarantined. See Error Handling.

Constants

const NATIVE_ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
const PRIVACY_ADDRESS_LENGTH = 194;
const PRIVACY_ADDRESS_HEX_LENGTH = 192;