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.

iOS Quickstart

Integrate private token transfers into your iOS app with the Swift SDK.
This quickstart gets you running in 5 minutes with minimal explanation. For detailed walkthroughs of each step, see the iOS Getting Started guide. For background on configuration and auth options, see Setup.

Installation

Swift Package Manager

Add to your Package.swift:
dependencies: [
    .package(url: "https://github.com/sunnyside-io/privacy-boost-sdk.git", from: "0.1.0")
]
Or in Xcode:
  1. File → Add Package Dependencies
  2. Enter the repository URL
  3. Select version and add to your target

Quick Example

1. Create Wallet Delegate

import PrivacyBoost

class MyWalletDelegate: WalletDelegate {
    private let wallet: YourWalletImplementation

    func getAddress() async throws -> String {
        return wallet.address
    }

    func getChainId() async throws -> UInt64 {
        return wallet.chainId
    }

    func signMessage(message: String) async throws -> String {
        return try await wallet.sign(message: message)
    }

    func signTypedData(typedDataJson: String) async throws -> String {
        return try await wallet.signTypedData(typedDataJson)
    }

    func sendTransaction(toAddress: String, value: String, data: String) async throws -> String {
        return try await wallet.sendTransaction(toAddress: toAddress, value: value, data: data)
    }

    func waitForTransactionReceipt(txHash: String) async throws -> TransactionReceipt {
        let receipt = try await wallet.waitForReceipt(txHash: txHash)
        return TransactionReceipt(
            txHash: txHash,
            status: receipt.status,
            logs: receipt.logs
        )
    }
}

2. Initialize and Use SDK

import PrivacyBoost

// 1. Create configuration — server discovers chainId / contracts when nil.
let config = PrivacyBoostConfig(
    serverUrl: "https://test-api.privacyboost.io",
    chainId: nil,
    shieldContractAddress: nil,
    wethContractAddress: "0x4200000000000000000000000000000000000006",
    teePublicKey: nil,
    appId: "app_abc123xyz",
    persistenceStorage: nil,
    persistenceUnlock: nil
)

// 2. Initialize SDK (synchronous, throwing).
let sdk = try PrivacyBoost(config: config)

// 3. Authenticate — keySource defaults to .walletDerived when persistence is off.
let walletDelegate = MyWalletDelegate()
let authResult = try await sdk.authenticate(
    wallet: walletDelegate,
    keySource: nil,
    tokenProvider: nil
)
switch authResult {
case .authenticated(let loginResult):
    print("Privacy address: \(loginResult.privacyAddress)")
case .credentialRequired(let challenge):
    // Prompt the user for their PIN / password, then submit it.
    let pin = try await promptUserForPin(challenge: challenge)
    let loginResult = try await sdk.submitCredential(pin, tokenProvider: nil)
    print("Privacy address: \(loginResult.privacyAddress)")
case .mnemonicGenerated(let mnemonic):
    // First-time user — show the mnemonic, confirm they saved it, then proceed.
    try await confirmMnemonicSaved(mnemonic)
    let loginResult = try await sdk.proceedAfterMnemonic(
        credential: nil,
        tokenProvider: nil
    )
    print("Privacy address: \(loginResult.privacyAddress)")
case .recoveryRequired(let challenge):
    // Local keys are missing but an account exists — prompt for the recovery
    // mnemonic and re-authenticate with `.mnemonic(phrase:)`.
    print("Recovery required: \(challenge)")
}
MnemonicGenerated fires for first-time users. CredentialRequired only fires when persistence with PIN / password / biometric unlock is configured. RecoveryRequired fires when the device has an account record but local keys are missing — prompt for the mnemonic and re-authenticate with .mnemonic(phrase:).
// 4. Check balance
let balance = try await sdk.getBalance(tokenAddress: "0x...")
print("Shielded: \(balance.shieldedBalance)")

// 5. Deposit
let shieldResult = try await sdk.shield(
    tokenAddress: "0x...",
    amount: "1000000000000000000" // 1 token (18 decimals)
)
print("Deposit tx: \(shieldResult.txHash)")

// 6. Transfer
let transferResult = try await sdk.send(
    tokenAddress: "0x...",
    amount: "500000000000000000", // 0.5 tokens
    recipientPrivacyAddress: recipientPrivacyAddress
)
print("Transfer tx: \(transferResult.txHash)")

// 7. Withdraw
let unshieldResult = try await sdk.unshield(
    tokenAddress: "0x...",
    amount: "250000000000000000", // 0.25 tokens
    recipient: "0x..."
)
print("Withdraw tx: \(unshieldResult.txHash)")

SwiftUI Example

import SwiftUI
import PrivacyBoost

struct ContentView: View {
    @StateObject private var viewModel = WalletViewModel()

    var body: some View {
        VStack {
            if viewModel.isAuthenticated {
                Text("Privacy Address:")
                Text(viewModel.privacyAddress ?? "")
                    .font(.caption)

                Button("Deposit 1 Token") {
                    Task { await viewModel.deposit() }
                }

                Button("Clear Session") {
                    viewModel.clearSession()
                }
            } else {
                Button("Connect Wallet") {
                    Task { await viewModel.authenticate() }
                }
            }
        }
    }
}

@MainActor
class WalletViewModel: ObservableObject {
    @Published var isAuthenticated = false
    @Published var privacyAddress: String?

    private var sdk: PrivacyBoost?

    func authenticate() async {
        do {
            let config = PrivacyBoostConfig(/* ... */)
            sdk = try PrivacyBoost(config: config)

            let wallet = MyWalletDelegate()
            let result = try await sdk?.authenticate(
                wallet: wallet,
                keySource: nil,
                tokenProvider: nil
            )
            switch result {
            case .authenticated(let loginResult):
                privacyAddress = loginResult.privacyAddress
                isAuthenticated = true
            case .mnemonicGenerated, .credentialRequired, .recoveryRequired:
                // Handle multi-step auth flows — see the Quick Example above.
                break
            case .none:
                break
            }
        } catch {
            print("Authentication failed: \(error)")
        }
    }

    func deposit() async {
        try? await sdk?.shield(
            tokenAddress: "0x...",
            amount: "1000000000000000000"
        )
    }

    func clearSession() {
        sdk?.clearSession()
        isAuthenticated = false
        privacyAddress = nil
    }
}

Next Steps

iOS Getting Started

Detailed walkthrough of each integration step

Setup Guide

App ID, configuration, and auth method selection

Wallet Integration

Detailed WalletDelegate implementation

Session Storage

Secure Keychain storage and biometric unlock