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.

Withdrawals

This guide covers withdrawing tokens from your private balance to any public Ethereum address.

Basic Withdrawal

do {
    let result = try await sdk.unshield(
        tokenAddress: "0x...token-address",
        amount: "1000000000000000000", // 1 token
        recipient: "0x...recipient-address"
    )
    print("Transaction hash: \(result.txHash)")
} catch {
    print("Withdrawal failed: \(error)")
}

Withdrawal Parameters

ParameterTypeRequiredDescription
tokenAddressStringYesToken contract address
amountStringYesAmount in wei (smallest unit)
recipientStringYesDestination Ethereum address

Withdrawal Steps

Withdrawals involve zero-knowledge proof generation, which can take up to 30 seconds:
StepDescription
PreparingPreparing withdrawal data
SigningSigning transaction data
ProvingGenerating zero-knowledge proof
UnshieldingExecuting withdrawal transaction
UnwrappingUnwrapping WETH to ETH (if applicable)

Withdrawal Result

struct UnshieldResult {
    let txHash: String  // Main withdrawal transaction hash
    let fee: String     // Fee paid (in wei)
}

Withdraw to Self

Withdraw to your connected wallet address:
let myAddress = sdk.getWalletAddress()!

let result = try await sdk.unshield(
    tokenAddress: "0x...",
    amount: "1000000000000000000",
    recipient: myAddress
)

Withdraw to Any Address

You can withdraw to any valid Ethereum address:
let recipientAddress = "0x..."

// Validate address first
guard sdk.isValidAddress(recipientAddress) else {
    print("Invalid recipient address")
    return
}

let result = try await sdk.unshield(
    tokenAddress: "0x...",
    amount: "1000000000000000000",
    recipient: recipientAddress
)

Partial Withdrawals

Withdraw any amount up to your shielded balance:
// Check available balance first
let balance = try await sdk.getBalance(tokenAddress: tokenAddress)

guard let shielded = UInt64(balance.shieldedBalance),
      let unshieldAmount = UInt64(amount),
      unshieldAmount <= shielded else {
    print("Insufficient shielded balance")
    return
}

let result = try await sdk.unshield(
    tokenAddress: tokenAddress,
    amount: amount,
    recipient: recipientAddress
)

Error Handling

do {
    let result = try await sdk.unshield(
        tokenAddress: tokenAddress,
        amount: amount,
        recipient: recipient
    )
} catch SDKError.insufficientBalance {
    print("Not enough shielded balance")
} catch SDKError.invalidAddress {
    print("Invalid recipient address")
} catch SDKError.invalidAmount {
    print("Invalid amount format")
} catch SDKError.walletError(let message) {
    print("Wallet error: \(message)")
} catch SDKError.networkError(let message) {
    print("Network error: \(message)")
} catch {
    print("Withdrawal error: \(error)")
}

Best Practices

1. Validate Balance Before Withdrawal

func validateWithdrawal(tokenAddress: String, amount: String) async throws {
    let balance = try await sdk.getBalance(tokenAddress: tokenAddress)

    guard let shielded = UInt64(balance.shieldedBalance),
          let requested = UInt64(amount),
          requested <= shielded else {
        throw SDKError.insufficientBalance
    }
}

2. Validate Recipient Address

func validateRecipient(_ address: String) throws {
    guard sdk.isValidAddress(address) else {
        throw SDKError.invalidAddress
    }
    guard address != "0x0000000000000000000000000000000000000000" else {
        throw SDKError.invalidAddress
    }
}

3. Handle Long Operations

Withdrawals include zero-knowledge proof generation which can take up to 30 seconds. Show a loading indicator and inform users about the expected wait time.
// Show estimated time in your UI
statusLabel.text = "Generating proof... This may take up to 30 seconds."

let result = try await sdk.unshield(
    tokenAddress: tokenAddress,
    amount: amount,
    recipient: recipient
)

statusLabel.text = "Withdrawal complete!"

Next Steps