Skip to main content

Getting Started

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

Overview

The Android SDK follows a simple flow:
  1. Initialize - Create SDK instance with configuration
  2. Connect - Connect wallet via WalletDelegate
  3. Login - Authenticate and get privacy address
  4. Use - Deposit, withdraw, transfer tokens

Basic Setup

1. Configure the SDK

import com.privacyboost.sdk.*

val config = SdkConfig(
    indexerUrl = "https://test-api.privacy-boost.sunnyside.io/indexer",
    proverUrl = "https://test-api.privacy-boost.sunnyside.io/prover",
    chainId = 11155420,
    shieldContract = "0xB22fD661b322F10d4B7cd0cFcb9578C485423119",
    wethContract = "0x4200000000000000000000000000000000000006"
)

2. Initialize

val sdk = PrivacyBoostSdk(config)

Connecting a Wallet

The SDK uses the WalletDelegate interface to interact with wallets:
import com.privacyboost.sdk.*

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

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

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

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

    override fun sendTransaction(toAddress: String, value: String, data: String): String {
        // Submit transaction and return hash
        return "0x..."
    }
}
Then connect:
val wallet = MyWalletDelegate()
try {
    val result = sdk.connect(wallet)
    println("Connected: ${result.walletAddress}")
    println("Privacy Address: ${result.privacyAddress}")
} catch (e: SDKError) {
    println("Connection failed: ${e.message}")
}

Authentication

After connecting, authenticate with the backend:
try {
    val loginResult = sdk.login()
    println("Privacy Address: ${loginResult.privacyAddress}")
    println("MPK: ${loginResult.mpk}")
} catch (e: SDKError) {
    println("Login failed: ${e.message}")
}

Core Operations

Check Balance

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:
try {
    val result = sdk.deposit(
        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:
try {
    val result = sdk.withdraw(
        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:
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:
import kotlinx.coroutines.*

class PrivacyBoostManager(private val sdk: PrivacyBoostSdk) {

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

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

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

Complete Example

import com.privacyboost.sdk.*
import kotlinx.coroutines.*

class PrivacyBoostRepository(config: SdkConfig) {
    private val sdk = PrivacyBoostSdk(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 connect(wallet: WalletDelegate): ConnectResult =
        withContext(Dispatchers.IO) {
            walletDelegate = wallet
            sdk.connect(wallet)
        }

    suspend fun login(): LoginResult =
        withContext(Dispatchers.IO) {
            sdk.login()
        }

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

    suspend fun withdraw(token: String, amount: String, recipient: String): WithdrawResult =
        withContext(Dispatchers.IO) {
            sdk.withdraw(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 disconnect() {
        sdk.disconnect()
        walletDelegate = null
    }
}

Error Handling

The SDK throws SDKError for various failure conditions:
try {
    val result = sdk.deposit(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:
// 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