> ## 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.

# Getting started

# Getting Started

This guide walks you through integrating the Privacy Boost Android SDK into your app.

<Info>
  For a minimal copy-paste example, see the [Android Quickstart](/sdk/quickstart/android). This guide explains each step in detail.
</Info>

## Prerequisites

* The SDK [installed](/sdk/android/installation) in your project
* An [App ID](/sdk/concepts/app-setup) and server URL (see [Configuration](/sdk/concepts/configuration))
* A wallet integration (WalletConnect, custom, etc.)
* Familiarity with [authentication options](/sdk/concepts/authentication) (optional for development, required for production)

## Overview

The Android SDK follows a simple flow:

1. **Initialize** - Create SDK instance with configuration
2. **Authenticate** - Connect wallet and authenticate via `WalletDelegate`
3. **Use** - Deposit, unshield, transfer tokens

## Basic Setup

### 1. Configure the SDK

```kotlin theme={null}
import com.privacyboost.sdk.*

val config = PrivacyBoostConfig(
    serverUrl = "https://optimism.sepolia.privacyboost.io",
    wethContractAddress = "0x4200000000000000000000000000000000000006",
    appId = "app_abc123xyz"
)
```

### 2. Initialize

```kotlin theme={null}
val sdk = PrivacyBoost(config)
```

## Connecting a Wallet

The SDK uses the `WalletDelegate` interface to interact with wallets:

```kotlin theme={null}
import com.privacyboost.sdk.*

class MyWalletDelegate : WalletDelegate {
    override suspend fun getAddress(): String {
        // Return the connected wallet address
        return "0x..."
    }

    override suspend fun getChainId(): ULong {
        // Return the current chain ID
        return 1UL
    }

    override suspend fun signMessage(message: String): String {
        // Sign using EIP-191 personal_sign
        // Return signature as hex string with 0x prefix
        return "0x..."
    }

    override suspend fun signTypedData(typedDataJson: String): String {
        // Sign using EIP-712 eth_signTypedData_v4
        return "0x..."
    }

    override suspend fun sendTransaction(toAddress: String, value: String, data: String): String {
        // Submit transaction and return hash
        return "0x..."
    }

    override suspend fun waitForTransactionReceipt(txHash: String): TransactionReceipt {
        // Poll eth_getTransactionReceipt until the transaction is mined
        return TransactionReceipt(txHash = txHash, status = true, logs = emptyList())
    }
}
```

Then authenticate:

```kotlin theme={null}
val wallet = MyWalletDelegate()
try {
    // Default (wallet-derived keys)
    val result = sdk.authenticate(wallet = wallet)

    // Or with a specific key source
    // val result = sdk.authenticate(
    //     wallet = wallet,
    //     keySource = KeySource.Mnemonic(phrase = "your twelve word mnemonic ...")
    // )

    when (result) {
        is AuthResult.Authenticated -> {
            println("Privacy Address: ${result.loginResult.privacyAddress}")
            println("MPK: ${result.loginResult.mpk}")
        }
        is AuthResult.CredentialRequired -> {
            // Handle credential challenge
            val loginResult = sdk.submitCredential(credential)
            println("Privacy Address: ${loginResult.privacyAddress}")
        }
    }
} catch (e: SDKError) {
    println("Authentication failed: ${e.message}")
}
```

## Core Operations

### Check Balance

```kotlin theme={null}
try {
    val balance = sdk.getBalance("0x...")
    println("Shielded: ${balance.shieldedBalance}")
    println("Wallet: ${balance.walletBalance}")
} catch (e: SDKError) {
    println("Failed to get balance: ${e.message}")
}
```

### Deposit Tokens

Move tokens from wallet to shielded pool:

```kotlin theme={null}
try {
    val result = sdk.shield(
        tokenAddress = "0x...",
        amount = "1000000000000000000"  // 1 token (18 decimals)
    )
    println("Deposit TX: ${result.txHash}")
} catch (e: SDKError) {
    println("Deposit failed: ${e.message}")
}
```

### Withdraw Tokens

Move tokens from shielded pool to wallet:

```kotlin theme={null}
try {
    val result = sdk.unshield(
        tokenAddress = "0x...",
        amount = "500000000000000000",
        recipient = "0x..."  // Recipient address
    )
    println("Withdraw TX: ${result.txHash}")
} catch (e: SDKError) {
    println("Withdraw failed: ${e.message}")
}
```

### Private Transfer

Send tokens privately to another user:

```kotlin theme={null}
try {
    val result = sdk.send(
        tokenAddress = "0x...",
        amount = "250000000000000000",
        recipientPrivacyAddress = "0x04..."  // 194-char privacy address
    )
    println("Transfer TX: ${result.txHash}")
} catch (e: SDKError) {
    println("Transfer failed: ${e.message}")
}
```

## Using with Coroutines

The SDK methods are blocking. Use coroutines for non-blocking calls:

```kotlin theme={null}
import kotlinx.coroutines.*

class PrivacyBoostManager(private val sdk: PrivacyBoost) {

    suspend fun shield(token: String, amount: String): ShieldResult =
        withContext(Dispatchers.IO) {
            sdk.shield(token, amount)
        }

    suspend fun getBalance(token: String): TokenBalance =
        withContext(Dispatchers.IO) {
            sdk.getBalance(token)
        }
}

// Usage
lifecycleScope.launch {
    try {
        val result = manager.shield(token, amount)
        // Update UI on main thread
        binding.txHashText.text = result.txHash
    } catch (e: SDKError) {
        showError(e.message)
    }
}
```

## Complete Example

```kotlin theme={null}
import com.privacyboost.sdk.*
import kotlinx.coroutines.*

class PrivacyBoostRepository(config: PrivacyBoostConfig) {
    private val sdk = PrivacyBoost(config)
    private var walletDelegate: WalletDelegate? = null

    val isConnected: Boolean
        get() = sdk.isConnected()

    val isAuthenticated: Boolean
        get() = sdk.isAuthenticated()

    val privacyAddress: String?
        get() = sdk.getPrivacyAddress()

    suspend fun authenticate(wallet: WalletDelegate): AuthResult =
        withContext(Dispatchers.IO) {
            walletDelegate = wallet
            sdk.authenticate(wallet)
        }

    suspend fun shield(token: String, amount: String): ShieldResult =
        withContext(Dispatchers.IO) {
            sdk.shield(token, amount)
        }

    suspend fun unshield(token: String, amount: String, recipient: String): UnshieldResult =
        withContext(Dispatchers.IO) {
            sdk.unshield(token, amount, recipient)
        }

    suspend fun send(token: String, amount: String, to: String): TransferResult =
        withContext(Dispatchers.IO) {
            sdk.send(token, amount, to)
        }

    suspend fun getBalance(token: String): TokenBalance =
        withContext(Dispatchers.IO) {
            sdk.getBalance(token)
        }

    fun logout() {
        sdk.logout()
        walletDelegate = null
    }
}
```

## Error Handling

The SDK throws `SDKError` for various failure conditions:

```kotlin theme={null}
try {
    val result = sdk.shield(token, amount)
} catch (e: SDKError.NotConnected) {
    println("Wallet not connected")
} catch (e: SDKError.NotAuthenticated) {
    println("Not logged in")
} catch (e: SDKError.InsufficientBalance) {
    println("Insufficient balance")
} catch (e: SDKError.InvalidAmount) {
    println("Invalid amount format")
} catch (e: SDKError.WalletError) {
    println("Wallet error: ${e.message}")
} catch (e: SDKError.NetworkError) {
    println("Network error: ${e.message}")
} catch (e: SDKError) {
    println("Unknown error: ${e.message}")
}
```

## Session Persistence

Save and restore sessions to avoid re-signing:

```kotlin theme={null}
// Export session
val session = sdk.exportSession()
session?.let {
    saveToSecureStorage(it)
}

// Import session
loadFromSecureStorage()?.let { session ->
    try {
        val success = sdk.importSession(session)
        if (success) {
            println("Session restored")
        }
    } catch (e: SDKError) {
        println("Session expired or invalid")
    }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Wallet Integration" href="/sdk/android/guides/wallet-integration">
    Detailed WalletDelegate implementation
  </Card>

  <Card title="Session Storage" href="/sdk/android/guides/session-storage">
    Android Keystore storage and biometric unlock
  </Card>

  <Card title="API Reference" href="/sdk/android/api-reference">
    Complete API documentation
  </Card>

  <Card title="Key Management" href="/sdk/concepts/key-management">
    Key derivation, persistence options, and recovery
  </Card>
</CardGroup>
