Error Handling
The Privacy Boost SDK uses structured error codes so you can handle errors programmatically. Every error has a stablecode string that won’t change between SDK versions.
Quick Example
Error Types by Platform
| Platform | Error Type | How to check the code |
|---|---|---|
| TypeScript | PrivacyBoostError | error.code, error.retryable, error.isAuthError() |
| iOS (Swift) | SDKError | catch SDKError.networkError(let msg) { ... } |
| Android (Kotlin) | SDKError | catch (e: SDKError.NetworkError) { ... } |
TypeScript: PrivacyBoostError
Error Codes
Wallet Errors
These occur when interacting with the user’s wallet.| Code | What happened | User action |
|---|---|---|
WALLET_NOT_CONNECTED | No wallet connected | Show “Connect Wallet” button |
WALLET_CONNECTION_FAILED | Wallet refused or failed to connect | Retry or try a different wallet |
WRONG_NETWORK | Wallet is on the wrong chain | Show “Switch Network” prompt |
TRANSACTION_REJECTED | User rejected a signature or transaction | Do nothing (intentional) |
TRANSACTION_FAILED | On-chain transaction failed | Show error, check gas/params |
INSUFFICIENT_GAS | Not enough gas for the transaction | Prompt user to add funds |
Authentication Errors
These occur during login or when a session expires.| Code | What happened | User action |
|---|---|---|
NOT_AUTHENTICATED | Tried to use SDK before logging in | Call authenticate() first |
SESSION_EXPIRED | JWT expired | Re-authenticate (can be automatic) |
AUTHENTICATION_FAILED | Login failed | Retry or check configuration |
Network Errors
These are transient and usually retryable.| Code | What happened | Retryable? |
|---|---|---|
NETWORK_ERROR | Connection failed (DNS, timeout, refused) | Yes |
TIMEOUT | Request took too long | Yes |
RATE_LIMITED | Too many requests (429) | Yes (with backoff) |
SERVICE_UNAVAILABLE | Backend is temporarily down | Yes (with backoff) |
Operation Errors
These occur during deposits, transfers, or withdrawals.| Code | What happened | User action |
|---|---|---|
INSUFFICIENT_BALANCE | Not enough shielded balance | Show balance and suggest depositing more |
INVALID_ADDRESS | Malformed Ethereum or privacy address | Prompt user to check the address |
INVALID_AMOUNT | Amount is zero, negative, or malformed | Validate input before calling the SDK |
INVALID_CONFIG | SDK configuration is invalid | Check appId, indexerUrl, and other config values |
Compliance Errors
These occur when a transaction fails compliance screening.| Code | What happened | User action |
|---|---|---|
COMPLIANCE_BLOCKED | Address or transaction blocked by compliance screening | Contact support |
TRANSFER_COMPLIANCE_FAILED | Transfer failed compliance check | Contact support |
Crypto Errors
These indicate failures in the cryptographic layer.| Code | What happened | User action |
|---|---|---|
CRYPTO_ERROR | General cryptographic operation failed | Report the issue |
ENCRYPTION_ERROR | Failed to encrypt data | Retry or re-authenticate |
DECRYPTION_ERROR | Failed to decrypt data (wrong keys or corrupted) | Re-authenticate or restore keys |
KEY_DERIVATION_ERROR | Failed to derive privacy keys | Re-authenticate |
Shield Errors
These occur during shield (deposit) operations.| Code | What happened | User action |
|---|---|---|
SHIELD_NOT_FOUND | Shield request not found on-chain | Check transaction hash |
SHIELD_ALREADY_CLAIMED | Shield has already been claimed | No action needed |
SHIELD_PROOF_EXPIRED | Shield proof has expired | Re-initiate the shield |
SHIELD_COMMITMENT_NOT_FOUND | On-chain commitment not found | Wait for indexer to sync |
Transfer Errors
These occur during private transfers.| Code | What happened | User action |
|---|---|---|
TRANSFER_NOT_FOUND | Transfer not found | Check request ID |
TRANSFER_PROOF_FAILED | ZK proof generation or verification failed | Retry the transfer |
TRANSFER_SUBMISSION_FAILED | Transfer could not be submitted to the server | Retry |
BELOW_MIN_TRANSFER_AMOUNT | Amount is below minimum transfer threshold | Increase amount |
Merkle Tree Errors
These occur during proof construction.| Code | What happened | Retryable? |
|---|---|---|
MERKLE_LEAF_NOT_FOUND | Note’s leaf not found in the Merkle tree | Yes (indexer may be syncing) |
MERKLE_PROOF_FAILED | Failed to construct Merkle proof | Yes |
MERKLE_ROOT_STALE | Merkle root is outdated | Yes (auto-retried by SDK) |
Note Errors
These occur when accessing private notes.| Code | What happened | User action |
|---|---|---|
NOTE_NOT_FOUND | Note does not exist | Verify the transaction |
NOTE_ALREADY_SPENT | Note has already been spent (nullifier exists) | No action — note was used |
NOTE_ACCESS_DENIED | Cannot decrypt this note (wrong keys) | Verify correct account |
Internal Errors
These indicate SDK bugs or unexpected server responses.| Code | What happened | User action |
|---|---|---|
SERIALIZATION_ERROR | Failed to serialize/deserialize data | Report the issue |
OPERATION_FAILED | Generic operation failure | Check the error message for details |
INTERNAL_ERROR | Unexpected internal error | Report the issue with full error details |
Recovery Patterns
Handle user rejections gracefully
When a user cancels a wallet popup, don’t show an error dialog — it’s intentional.Retry on network errors
Useerror.retryable with exponential backoff:
Re-authenticate on session expiry
Map errors to user-friendly messages
Best Practices
-
Match on
error.code, noterror.message. Codes are stable across versions; messages may change. - Never show raw error messages to users. Map codes to context-appropriate messages.
-
Handle
TRANSACTION_REJECTEDsilently. The user intentionally cancelled. -
Use
error.retryablefor retry logic. The SDK marks transient errors as retryable. -
Log the full error internally. Capture
code,message, andcausefor debugging, even when showing a simple message to the user.
Next Steps
You’ve completed the Setup section. Now dive into your platform SDK:TypeScript
Full web SDK guide
React
Hooks and components
iOS
Native Swift SDK
Android
Native Kotlin SDK
React Native
React Native SDK
CLI
Command-line tool