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.
Android Quickstart
Integrate private token transfers into your Android app with the Kotlin SDK.
This quickstart gets you running in 5 minutes with minimal explanation. For detailed walkthroughs of each step, see the Android Getting Started guide. For background on configuration and auth options, see Setup.
Installation
Gradle
Add to your build.gradle.kts:
dependencies {
implementation("io.privacy-boost:privacy-boost-android:1.0.0")
}
Or for Groovy (build.gradle):
dependencies {
implementation 'io.privacy-boost:privacy-boost-android:1.0.0'
}
Quick Example
1. Create Wallet Delegate
import com.privacyboost.sdk.*
class MyWalletDelegate(private val wallet: YourWalletImplementation) : WalletDelegate {
override suspend fun getAddress(): String {
return wallet.address
}
override suspend fun getChainId(): ULong {
return wallet.chainId.toULong()
}
override suspend fun signMessage(message: String): String {
return wallet.sign(message)
}
override suspend fun signTypedData(typedDataJson: String): String {
return wallet.signTypedData(typedDataJson)
}
override suspend fun sendTransaction(toAddress: String, value: String, data: String): String {
return wallet.sendTransaction(toAddress, value, data)
}
override suspend fun waitForTransactionReceipt(txHash: String): TransactionReceipt {
val receipt = wallet.waitForReceipt(txHash)
return TransactionReceipt(
txHash = txHash,
status = receipt.status,
logs = receipt.logs,
)
}
}
2. Initialize and Use SDK
import com.privacyboost.sdk.*
import kotlinx.coroutines.launch
// 1. Create configuration — server discovers chainId / contracts when null.
val config = PrivacyBoostConfig(
serverUrl = "https://test-api.privacyboost.io",
chainId = null,
shieldContractAddress = null,
wethContractAddress = "0x4200000000000000000000000000000000000006",
teePublicKey = null,
appId = "app_abc123xyz",
persistenceStorage = null,
persistenceUnlock = null,
)
// 2. Initialize SDK
val sdk = PrivacyBoost(config)
// 3. Authenticate — keySource defaults to WalletDerived when persistence is off.
lifecycleScope.launch {
val walletDelegate = MyWalletDelegate(wallet)
val authResult = sdk.authenticate(
wallet = walletDelegate,
keySource = null,
tokenProvider = null,
)
when (authResult) {
is AuthResult.Authenticated -> {
println("Privacy address: ${authResult.loginResult.privacyAddress}")
}
is AuthResult.CredentialRequired -> {
// Prompt the user for their PIN / password, then submit it.
val pin = promptUserForPin(authResult.challenge)
val loginResult = sdk.submitCredential(pin, tokenProvider = null)
println("Privacy address: ${loginResult.privacyAddress}")
}
is AuthResult.MnemonicGenerated -> {
// First-time user — show the mnemonic, confirm they saved it,
// then proceed.
confirmMnemonicSaved(authResult.mnemonic)
val loginResult = sdk.proceedAfterMnemonic(
credential = null,
tokenProvider = null,
)
println("Privacy address: ${loginResult.privacyAddress}")
}
is AuthResult.RecoveryRequired -> {
// Local keys are missing but an account exists — prompt for the
// recovery mnemonic and re-authenticate with KeySource.Mnemonic.
println("Recovery required: ${authResult.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 KeySource.Mnemonic(phrase).
// 4. Check balance
val balance = sdk.getBalance("0x...")
println("Shielded: ${balance.shieldedBalance}")
// 5. Deposit
val shieldResult = sdk.shield(
tokenAddress = "0x...",
amount = "1000000000000000000" // 1 token (18 decimals)
)
println("Deposit tx: ${shieldResult.txHash}")
// 6. Transfer
val transferResult = sdk.send(
tokenAddress = "0x...",
amount = "500000000000000000", // 0.5 tokens
recipientPrivacyAddress = recipientPrivacyAddress
)
println("Transfer tx: ${transferResult.txHash}")
// 7. Withdraw
val unshieldResult = sdk.unshield(
tokenAddress = "0x...",
amount = "250000000000000000", // 0.25 tokens
recipient = "0x..."
)
println("Withdraw tx: ${unshieldResult.txHash}")
Jetpack Compose Example
import androidx.compose.runtime.*
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.privacyboost.sdk.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class WalletViewModel : ViewModel() {
private val _isAuthenticated = MutableStateFlow(false)
val isAuthenticated: StateFlow<Boolean> = _isAuthenticated
private val _privacyAddress = MutableStateFlow<String?>(null)
val privacyAddress: StateFlow<String?> = _privacyAddress
private var sdk: PrivacyBoost? = null
fun authenticate(wallet: WalletDelegate) {
viewModelScope.launch {
try {
val config = PrivacyBoostConfig(/* ... */)
sdk = PrivacyBoost(config)
val result = sdk?.authenticate(
wallet = wallet,
keySource = null,
tokenProvider = null,
)
when (result) {
is AuthResult.Authenticated -> {
_privacyAddress.value = result.loginResult.privacyAddress
_isAuthenticated.value = true
}
is AuthResult.MnemonicGenerated,
is AuthResult.CredentialRequired,
is AuthResult.RecoveryRequired -> {
// Handle multi-step auth flows — see the Quick Example above.
}
null -> {}
}
} catch (e: Exception) {
println("Authentication failed: ${e.message}")
}
}
}
fun deposit(tokenAddress: String, amount: String) {
viewModelScope.launch {
sdk?.shield(tokenAddress = tokenAddress, amount = amount)
}
}
fun clearSession() {
sdk?.clearSession()
_isAuthenticated.value = false
_privacyAddress.value = null
}
}
@Composable
fun WalletScreen(viewModel: WalletViewModel = viewModel()) {
val isAuthenticated by viewModel.isAuthenticated.collectAsState()
val privacyAddress by viewModel.privacyAddress.collectAsState()
Column {
if (isAuthenticated) {
Text("Privacy Address:")
Text(privacyAddress ?: "", style = MaterialTheme.typography.caption)
Button(onClick = {
viewModel.deposit("0x...", "1000000000000000000")
}) {
Text("Deposit 1 Token")
}
Button(onClick = { viewModel.clearSession() }) {
Text("Clear Session")
}
} else {
Button(onClick = {
viewModel.authenticate(MyWalletDelegate(wallet))
}) {
Text("Connect Wallet")
}
}
}
}
Next Steps
Android Getting Started
Detailed walkthrough of each integration step
Setup Guide
App ID, configuration, and auth method selection
Wallet Integration
Detailed WalletDelegate implementation
Session Storage
Android Keystore storage and biometric unlock