Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt

Use this file to discover all available pages before exploring further.

API Reference

Complete API reference for the Privacy Boost React Native SDK (version 0.2.14). Everything below is derived from the generated UniFFI bindings — signatures match what consumers actually see.

Module exports

import {
  PrivacyBoost,
  PrivacyBoostConfig,
  ChainContextHandle,
  ChainContextConfig,
  KeySource,
  SdkError,
  SdkError_Tags,
  AuthResult,
  sdkVersion,
  generateMnemonic,
} from '@sunnyside-io/privacy-boost-react-native';
Top-level functions:
sdkVersion(): string          // Current SDK version string
generateMnemonic(): string    // Random BIP-39 12-word mnemonic

PrivacyBoost

Main SDK class. One instance per app; hold it in a module-level ref or a context provider.

Constructor

new PrivacyBoost(config: PrivacyBoostConfig)
Configs are created via the factory:
const config = PrivacyBoostConfig.create({
  serverUrl: 'https://indexer.example.com',
  chainId: undefined,                   // discovered from server if omitted
  shieldContractAddress: undefined,     // discovered from server if omitted
  wethContractAddress: '0x...' || undefined,
  teePublicKey: undefined,              // discovered from server if omitted
  appId: 'app_...',
  persistenceStorage: undefined, // StorageBackend.OsKeychain | .LocalStorage | .IndexedDb
  persistenceUnlock: undefined,  // UnlockMethod.None | .Pin | .Password | .Biometric | .Passkey
});

const sdk = new PrivacyBoost(config);
Throws: SdkError.InternalError if initialization fails (e.g. malformed server URL).

State

sdk.isConnected(): boolean
sdk.isAuthenticated(): boolean
sdk.getPrivacyAddress(): string | undefined
sdk.getMpk(): string | undefined
sdk.getWalletAddress(): string | undefined
sdk.getMnemonic(): string | undefined                   // throws

Authentication

sdk.authenticate(
  wallet: WalletDelegate,
  keySource: KeySource | undefined,
  tokenProvider: TokenProvider | undefined,
): Promise<AuthResult>
Connect a wallet, derive privacy keys, authenticate with the backend. Returns an AuthResult tagged union — see AuthResult for all variants and handling.
sdk.submitCredential(
  credential: string,
  tokenProvider: TokenProvider | undefined,
): Promise<LoginResult>
Complete an authentication flow that returned CredentialRequired.
sdk.proceedAfterMnemonic(
  tokenProvider: TokenProvider | undefined,
): Promise<LoginResult>
Complete an authentication flow that returned MnemonicGenerated (first-time user). Call this after the user confirms they’ve saved the recovery phrase.
sdk.logout(): void                  // End session, clear all state
sdk.clearSession(): void            // Clear JWT only, keep keys for quick re-auth
sdk.deleteVault(): Promise<void>    // Erase persisted vault on the device

Operations

sdk.shield(tokenAddress: string, amount: string): Promise<ShieldResult>
sdk.unshield(tokenAddress: string, amount: string, recipient: string): Promise<UnshieldResult>
sdk.send(tokenAddress: string, amount: string, recipientPrivacyAddress: string): Promise<TransferResult>
sdk.unwrapWeth(amount: string, recipientAddress: string): Promise<string>
unwrapWeth unwraps WETH the user already holds in their wallet back to native ETH — it does not interact with the shielded pool.

Status polling

sdk.getShieldStatus(requestId: string): Promise<ShieldStatus>
sdk.getTransferStatus(id: string): Promise<TransactionStatus>
sdk.getUnshieldStatus(id: string): Promise<TransactionStatus>

Balances & tokens

sdk.getBalance(tokenAddress: string): Promise<TokenBalance>
sdk.getAllBalances(): Promise<TokenBalance[]>
sdk.getRegisteredTokens(): RegisteredToken[]            // throws
sdk.getTokenByAddress(address: string): RegisteredToken // throws
sdk.getFees(tokenId: number): Promise<FeeRates>

History & notes

sdk.getTransactionHistory(
  txType: string | undefined,
  limit: number | undefined,
  cursor: string | undefined,
): Promise<TransactionsResult>

sdk.getUnspentNotes(tokenAddress: string | undefined): Promise<UnspentNote[]>

Pool observability

sdk.getMerkleTreeStats(): Promise<MerkleTreeStats>
sdk.getPoolStats(): Promise<PoolStats>

Audit APIs

For auditable operations — returns all-party visible data, not just the calling user’s. Intended for compliance dashboards and regulators, not for end-user UIs.
sdk.getAuditTransactions(
  pubkey?: string,
  txType?: string,
  limit?: number,
  offset?: number,
): Promise<AuditTransactionsResult>

sdk.getAuditNotes(
  owner?: string,
  tokenAddress?: string,
  spent?: boolean,
  limit?: number,
  offset?: number,
): Promise<AuditNotesResult>

sdk.getAuditBalances(
  pubkey?: string,
  tokenAddress?: string,
  limit?: number,
  offset?: number,
): Promise<AuditBalancesResult>

App metadata

sdk.getAppInfo(appIds: string[]): Promise<AppInfoEntry[]>

Session persistence

sdk.exportSession(): ExportedSession | undefined
sdk.importSession(session: ExportedSession): boolean

Identity lookup

sdk.resolveIdentity(identifier: string): IdentityResult   // throws

Pending transactions

Local bookkeeping for optimistic UI — not persisted across SDK instances.
sdk.addPendingTransaction(tx: PendingTransaction): void
sdk.getPendingTransactions(): PendingTransaction[]
sdk.getAllPendingTransactions(): PendingTransaction[]
sdk.refreshPendingTransactions(): Promise<number>       // returns updated count

Chain context

Create a handle scoped to a different chain while sharing the same SDK identity.
sdk.createChainContext(config: ChainContextConfig): ChainContextHandle
See ChainContextHandle below.

Delegates

sdk.setKeychainDelegate(delegate: KeychainDelegate): void
sdk.setPasskeyDelegate(delegate: PasskeyDelegate): void
sdk.setBiometricDelegate(delegate: BiometricDelegate): void

Utilities

sdk.isValidAddress(address: string): boolean
sdk.isValidPrivacyAddress(address: string): boolean
sdk.toChecksumAddress(address: string): string | undefined
sdk.parseAmount(amount: string, decimals: number): string    // throws
sdk.formatAmount(wei: string, decimals: number): string      // throws

ChainContextHandle

Returned by sdk.createChainContext(). Mirrors the main SDK’s chain-scoped operations against a different chain, without requiring a second authentication.
ctx.chainId(): bigint
ctx.isAuthenticated(): boolean
ctx.isRegistered(): boolean
ctx.authenticate(wallet: WalletDelegate): Promise<LoginResult>

ctx.shield(tokenAddress: string, amount: string): Promise<ShieldResult>
ctx.unshield(tokenAddress: string, amount: string, recipient: string): Promise<UnshieldResult>
ctx.send(tokenAddress: string, amount: string, recipientPrivacyAddress: string): Promise<TransferResult>
ctx.unwrapWeth(amount: string, recipient: string): Promise<string>

ctx.getBalance(tokenAddress: string): Promise<TokenBalance>
ctx.getAllBalances(): Promise<TokenBalance[]>
ctx.getRegisteredTokens(): Promise<RegisteredToken[]>
ctx.getTokenByAddress(address: string): Promise<RegisteredToken>
ctx.getFees(tokenId: number): Promise<FeeRates>

ctx.getShieldStatus(requestId: string): Promise<ShieldStatus>
ctx.getTransferStatus(id: string): Promise<TransactionStatus>
ctx.getUnshieldStatus(id: string): Promise<TransactionStatus>

ctx.getTransactionHistory(txType?: string, limit?: number, cursor?: string): Promise<TransactionsResult>
ctx.getUnspentNotes(tokenAddress?: string): Promise<UnspentNote[]>

ctx.addPendingTransaction(tx: PendingTransaction): void
ctx.getPendingTransactions(): PendingTransaction[]
ctx.getAllPendingTransactions(): PendingTransaction[]
ctx.refreshPendingTransactions(): Promise<number>

ctx.clearSession(): void

Delegate interfaces

WalletDelegate

interface WalletDelegate {
  getAddress(): Promise<string>;
  getChainId(): Promise<bigint>;
  signMessage(message: string): Promise<string>;
  signTypedData(typedDataJson: string): Promise<string>;
  sendTransaction(toAddress: string, value: string, data: string): Promise<string>;
  waitForTransactionReceipt(txHash: string): Promise<TransactionReceipt>;
}

interface TransactionReceipt {
  txHash: string;
  status: boolean;
  logs: Array<{ address: string; topics: string[]; data: string }>;
}

KeychainDelegate

interface KeychainDelegate {
  store(key: string, value: Uint8Array, requireBiometry: boolean): Promise<void>;
  load(key: string): Promise<Uint8Array | null>;
  remove(key: string): Promise<void>;
  contains(key: string): Promise<boolean>;
  isAvailable(): boolean;
  supportsBiometry(): boolean;
}

PasskeyDelegate

interface PasskeyDelegate {
  createCredential(rpId: string, userId: string, userName: string): Promise<PasskeyCredentialResult>;
  getAssertion(rpId: string, credentialIds: Uint8Array[], prfSalts: Uint8Array[]): Promise<PasskeyAssertionResult>;
  isAvailable(): boolean;
}

BiometricDelegate

interface BiometricDelegate {
  authenticate(reason: string): Promise<BiometricAuthenticationResult>;
  getCapabilities(): Promise<BiometricCapabilityResult>;
  storeSecret(key: string, secret: Uint8Array): Promise<void>;
  retrieveSecret(key: string): Promise<Uint8Array | null>;
  deleteSecret(key: string): Promise<void>;
}

TokenProvider

interface TokenProvider {
  getToken(loginPayloadJson: string): Promise<TokenResponse>;
}

interface TokenResponse {
  token: string;
  expiresIn: bigint;
}

Types

PrivacyBoostConfig

type PrivacyBoostConfig = {
  serverUrl: string;
  chainId: bigint | undefined;
  shieldContractAddress: string | undefined;
  wethContractAddress: string | undefined;
  teePublicKey: string | undefined;
  appId: string;
  persistenceStorage: StorageBackend | undefined;
  persistenceUnlock: UnlockMethod | undefined;
};

ChainContextConfig

type ChainContextConfig = {
  serverUrl: string;
  chainId: bigint;
  shieldContractAddress: string | undefined;
  wethContractAddress: string | undefined;
  rpcUrl: string | undefined;
  teePublicKey: string | undefined;
  timeoutMs: bigint;
};

KeySource

Tagged union — each variant is constructable.
new KeySource.WalletDerived()
new KeySource.Mnemonic('twelve word phrase')
new KeySource.RawSeed('0xdeadbeef...')

StorageBackend

enum StorageBackend {
  LocalStorage = 'LocalStorage',
  IndexedDb = 'IndexedDb',
  OsKeychain = 'OsKeychain',
}

UnlockMethod

enum UnlockMethod {
  None = 'None',
  Pin = 'Pin',
  Password = 'Password',
  Biometric = 'Biometric',
  Passkey = 'Passkey',
}

AuthResult

Tagged union returned by authenticate(). You must handle all four variants.
type AuthResult =
  | { tag: 'Authenticated'; loginResult: LoginResult }
  | { tag: 'CredentialRequired'; challenge: CredentialChallenge }
  | { tag: 'MnemonicGenerated'; mnemonic: string }
  | { tag: 'RecoveryRequired'; challenge: RecoveryChallenge };
See Getting Started → Connecting a Wallet for worked handling of each variant.

LoginResult

interface LoginResult {
  privacyAddress: string;
  mpk: string;
  isNewUser: boolean;
  chainRegistrations: Map<string, string>;  // chainId → registration tx hash
}

ShieldResult

interface ShieldResult {
  txHash: string;
  commitment: string;
  requestId: string;
  warning?: string;
  wrapTxHash?: string;   // present when shielding native ETH
}

UnshieldResult / TransferResult

interface UnshieldResult { requestId: string; txHash: string; fee: string; }
interface TransferResult { requestId: string; txHash: string; fee: string; }

ShieldStatus / TransactionStatus

interface ShieldStatus {
  id: string;
  status: string;         // "pending" | "confirmed" | "failed" | ...
  createdAt?: string;
  updatedAt?: string;
  txHash?: string;
  leafIndex?: bigint;
  error?: string;
}

interface TransactionStatus {
  id: string;
  txType: string;
  status: string;
  createdAt?: string;
  updatedAt?: string;
  txHash?: string;
  error?: string;
}

TokenBalance

interface TokenBalance {
  tokenAddress: string;
  shieldedBalance: string;   // in wei
  walletBalance: string;     // in wei
  symbol?: string;
  decimals: number;
}

RegisteredToken

interface RegisteredToken {
  id: number;
  tokenType: number;
  tokenAddress: string;
  tokenSubId: string;
  priceUsd?: number;
  decimals?: number;
  minShieldAmount?: string;
}

FeeRates

interface FeeRates {
  transferFeeFlat: string;   // flat fee in wei
  unshieldFeeBps: number;    // basis points
}

Transaction / TransactionNote / TransactionsResult

interface TransactionNote {
  value: string;
  direction: string;          // "incoming" | "outgoing"
  isChange: boolean;
  leafIndex?: bigint;
  nullifier?: string;
  counterparty?: string;
  counterpartyType?: string;
}

interface Transaction {
  txHash: string;
  txType: string;             // "shield" | "unshield" | "transfer"
  direction: string;
  value: string;
  tokenId: bigint;
  createdAt: bigint;
  counterparty?: string;
  counterpartyType?: string;
  notes: TransactionNote[];
}

interface TransactionsResult {
  data: Transaction[];
  limit: number;
  next?: string;              // cursor for next page
}

UnspentNote

interface UnspentNote {
  commitment: string;
  value: string;
  tokenAddress: string;
  tokenId: string;
  random: string;
  owner: string;
  spent: boolean;
  isOpaque: boolean;
  createdAt: bigint;
  leafIndex?: bigint;
  treeNumber?: bigint;
}

MerkleTreeStats / PoolStats

interface MerkleTreeStats { size: string; depth: string; root: string; }
interface PoolStats       { merkleTree: MerkleTreeStats; fetchedAt: string; }

Audit result types

interface AuditTransactionEntry { /* ...tx_hash, tx_type, value_in/out, ... */ }
interface AuditNoteEntry        { /* ...commitment, owner, value, spent, ... */ }
interface AuditBalanceEntry     { /* ...pub_key, token, balance, tx_count, ... */ }

interface AuditTransactionsResult { transactions: AuditTransactionEntry[]; total: bigint; limit: number; offset: number; }
interface AuditNotesResult        { notes: AuditNoteEntry[];        total: bigint; limit: number; offset: number; }
interface AuditBalancesResult     { balances: AuditBalanceEntry[];  total: bigint; limit: number; offset: number; }
See the generated bindings for full field lists; they’re stable but verbose.

PendingTransaction

enum PendingTransactionType      { Shield = 'Shield', Unshield = 'Unshield', Transfer = 'Transfer' }
enum PendingTransactionStatus    { Pending = 'Pending', Preconfirmed = 'Preconfirmed', Completed = 'Completed', Failed = 'Failed', Blocked = 'Blocked' }
enum PendingTransactionDirection { Incoming = 'Incoming', Outgoing = 'Outgoing' }

interface PendingTransaction {
  txHash: string;
  txType: PendingTransactionType;
  status: PendingTransactionStatus;
  direction: PendingTransactionDirection;
  error?: string;
  tokenAddress?: string;
  amount?: string;
  from?: string;
  to?: string;
  receivers: PendingReceiverTransfer[];
  createdAt: bigint;
  updatedAt: bigint;
  tokenSymbol?: string;
  commitment?: string;
  requestId?: string;
  isChange: boolean;
}

ExportedSession

interface ExportedSession {
  version: number;
  walletPublicKeyX: string;
  walletPublicKeyY: string;
  viewingKey: string;
  viewingPublicKeyX: string;
  viewingPublicKeyY: string;
  nullifyingKey: string;
  nullifyingPublicKeyX: string;
  nullifyingPublicKeyY: string;
  mpk: string;
  accountSalt: string;
  accountId: string;
  jwt: string;
  jwtExpiry: bigint;
  walletAddress: string;
}

IdentityResult

interface IdentityResult {
  mpk: string;
  viewingPublicKeyX: string;
  viewingPublicKeyY: string;
  privacyAddress: string;
}

AppInfoEntry

interface AppInfoEntry {
  appId: string;
  name: string;
  description?: string;
}

SdkError

Tagged union. Every variant is a constructable class, checked via .instanceOf(err). See the Error Handling guide for patterns and the full variant table.
SdkError.NotConnected.instanceOf(err)
SdkError.NotAuthenticated.instanceOf(err)
SdkError.NetworkError.instanceOf(err)
SdkError.WalletError.instanceOf(err)
SdkError.SignatureRejected.instanceOf(err)
SdkError.InsufficientBalance.instanceOf(err)
SdkError.InvalidAddress.instanceOf(err)
SdkError.InvalidAmount.instanceOf(err)
SdkError.SerializationError.instanceOf(err)
SdkError.AuthServerError.instanceOf(err)
SdkError.ShieldError.instanceOf(err)
SdkError.TransferError.instanceOf(err)
SdkError.NoteError.instanceOf(err)
SdkError.MerkleError.instanceOf(err)
SdkError.ApiError.instanceOf(err)
SdkError.RateLimited.instanceOf(err)
SdkError.Forbidden.instanceOf(err)
SdkError.ResourceNotFound.instanceOf(err)
SdkError.InternalError.instanceOf(err)
The string tag is also available at runtime via SdkError_Tags:
if (err.tag === SdkError_Tags.NotConnected) { ... }