> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kotlin SDK Reference Overview

## Overview

The Dynamic Kotlin SDK provides a comprehensive API for building Web3-enabled Android applications. This reference documents all the modules, functions, and types available in the SDK.

## Requirements

* Android API Level 26+
* Kotlin 1.9+
* Gradle 8.0+

## Installation

```kotlin theme={"system"}
// build.gradle.kts
dependencies {
    implementation("com.dynamic:android-sdk:VERSION")
}
```

## SDK Architecture

The SDK uses a singleton pattern with modular access to different functionalities:

```kotlin theme={"system"}
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.DynamicSDKConfig

// Initialize at app launch (in Application or MainActivity)
DynamicSDK.initialize(
    context = applicationContext,
    config = DynamicSDKConfig(
        environmentId = "YOUR_ENV_ID"
    )
)

// Access SDK instance
val sdk = DynamicSDK.getInstance()

// Access modules
sdk.auth       // Authentication
sdk.wallets    // Wallet management
sdk.evm        // EVM chain operations
sdk.solana     // Solana operations
sdk.networks   // Available networks
sdk.mfa        // Multi-factor authentication
sdk.passkeys   // Passkey management
sdk.ui         // Built-in UI components
```

## Core Modules

### Initialization

```kotlin theme={"system"}
// Initialize SDK (call once at app launch)
DynamicSDK.initialize(
    context = applicationContext,
    config = DynamicSDKConfig(
        environmentId = "YOUR_ENV_ID"
    )
)

// Get SDK instance
val sdk = DynamicSDK.getInstance()
```

### Authentication (`sdk.auth`)

```kotlin theme={"system"}
// Current user
val user = sdk.auth.authenticatedUser

// Auth token
val token = sdk.auth.token

// Reactive flows (Kotlin Coroutines)
sdk.auth.authenticatedUserChanges  // StateFlow<UserProfile?>
sdk.auth.tokenChanges              // StateFlow<String?>

// Logout
sdk.auth.logout()

// Email OTP
sdk.auth.email.sendOTP("user@example.com")
sdk.auth.email.verifyOTP("123456")
sdk.auth.email.resendOTP()

// SMS OTP
val phoneData = PhoneData(dialCode = "+1", iso2 = "US", phone = "5551234567")
sdk.auth.sms.sendOTP(phoneData)
sdk.auth.sms.verifyOTP("123456")
sdk.auth.sms.resendOTP()

// Social authentication
sdk.auth.social.connect(SocialAuthModule.SocialProvider.GOOGLE)
sdk.auth.social.connect(SocialAuthModule.SocialProvider.APPLE)
sdk.auth.social.connect(SocialAuthModule.SocialProvider.FARCASTER)

// Passkey authentication
sdk.auth.passkey.signIn()

// External JWT
sdk.auth.externalAuth.signInWithExternalJwt(
    SignInWithExternalJwtParams(jwt = "your-jwt")
)
```

### Wallets (`sdk.wallets`)

```kotlin theme={"system"}
// Current wallets
val wallets = sdk.wallets.userWallets  // List<BaseWallet>

// Reactive flow (Kotlin Coroutines)
sdk.wallets.userWalletsChanges  // StateFlow<List<BaseWallet>>

// Get balance
val balance = sdk.wallets.getBalance(wallet)

// Get current network
val network = sdk.wallets.getNetwork(wallet)

// Switch network
sdk.wallets.switchNetwork(wallet, targetNetwork)

// Set primary wallet
sdk.wallets.setPrimary(walletId)

// Sign message
val signature = sdk.wallets.signMessage(wallet, "Hello")

// Sign typed data (EIP-712)
val signature = sdk.wallets.signTypedData(wallet, typedDataJson)

// Verify signature
val isValid = sdk.wallets.verifySignature(
    wallet = wallet,
    message = "Hello",
    signature = signature
)
```

### EVM Operations (`sdk.evm`)

```kotlin theme={"system"}
// Create public client for chain
val client = sdk.evm.createPublicClient(chainId = 1)

// Get gas price
val gasPrice = client.getGasPrice()

// Send transaction
val transaction = EthereumTransaction(
    to = "0x...",
    value = "1000000000000000",  // Wei as String
    gasLimit = 21000,
    maxFeePerGas = gasPrice,
    maxPriorityFeePerGas = gasPrice
)
val txHash = sdk.evm.sendTransaction(wallet, transaction)

// Sign transaction (without sending)
val signedTx = sdk.evm.signTransaction(wallet, transaction)

// Write to contract
val input = WriteContractInput(
    address = "0x...",
    functionName = "transfer",
    args = listOf(recipient, amount),
    abi = listOf(/* ABI maps */)
)
val txHash = sdk.evm.writeContract(wallet, input)
```

### Solana Operations (`sdk.solana`)

```kotlin theme={"system"}
// Create connection
val connection = sdk.solana.createConnection()

// Get latest blockhash
val blockhashResult = connection.getLatestBlockhash()
val blockhash = blockhashResult.blockhash

// Create signer
val signer = sdk.solana.createSigner(wallet)

// Sign message
val signature = signer.signMessage("Hello")

// Sign transaction
val signedTx = signer.signEncodedTransaction(base64Transaction)

// Sign and send transaction
val signature = signer.signAndSendEncodedTransaction(base64Transaction)
```

### Networks (`sdk.networks`)

```kotlin theme={"system"}
// Available EVM networks
val evmNetworks = sdk.networks.evm  // List<GenericNetwork>

// Available Solana networks
val solanaNetworks = sdk.networks.solana  // List<GenericNetwork>

// Network properties
network.name        // String
network.chainId     // For EVM
network.networkId   // For Solana
```

### MFA (`sdk.mfa`)

```kotlin theme={"system"}
// Get user devices
val devices = sdk.mfa.getUserDevices()

// Add TOTP device (returns MfaAddDevice with secret)
val device = sdk.mfa.addDevice("totp")

// Verify device
sdk.mfa.verifyDevice("123456", "totp")

// Authenticate device to get MFA token
val token = sdk.mfa.authenticateDevice(
    MfaAuthenticateDevice(
        code = "123456",
        deviceId = deviceId,
        createMfaToken = MfaCreateToken(singleUse = true)
    )
)

// Delete device (requires MFA token)
sdk.mfa.deleteUserDevice(deviceId, mfaAuthToken = token)

// Recovery codes
val codes = sdk.mfa.getRecoveryCodes(generateNewCodes = false)
sdk.mfa.acknowledgeRecoveryCodes()  // Mark codes as shown to user
sdk.mfa.authenticateRecoveryCode(recoveryCode)
```

### Passkeys (`sdk.passkeys`)

```kotlin theme={"system"}
// Get user's passkeys
val passkeys = sdk.passkeys.getPasskeys()

// Register new passkey
sdk.passkeys.registerPasskey()

// Authenticate with passkey for MFA
val response = sdk.passkeys.authenticatePasskeyMFA(
    createMfaToken = MfaCreateToken(singleUse = true),
    relatedOriginRpId = null
)

// Delete passkey
sdk.passkeys.deletePasskey(
    DeletePasskeyRequest(passkeyId = passkeyId)
)

// Passkey properties
passkey.id              // String - Unique identifier
passkey.createdAt       // String - Creation timestamp (ISO format)
passkey.lastUsedAt      // String? - Last authentication time
passkey.isDefault       // Boolean? - Whether this is the default passkey
```

### Built-in UI (`sdk.ui`)

```kotlin theme={"system"}
// Show authentication UI
sdk.ui.showAuth()

// Show user profile
sdk.ui.showUserProfile()
```

## Data Types

### DynamicSDKConfig

```kotlin theme={"system"}
DynamicSDKConfig(
    environmentId: String      // Required
)
```

### BaseWallet

```kotlin theme={"system"}
wallet.address      // String - Wallet address
wallet.chain        // String - "EVM" or "SOL"
wallet.walletName   // String? - Wallet name
wallet.id           // String? - Wallet ID for API operations
```

### UserProfile

```kotlin theme={"system"}
user.userId         // String?
user.email          // String?
user.phoneNumber    // String?
// Additional properties available
```

### PhoneData

```kotlin theme={"system"}
PhoneData(
    dialCode: String,   // e.g., "+1"
    iso2: String,       // e.g., "US"
    phone: String       // Phone number without country code
)
```

### WriteContractInput

```kotlin theme={"system"}
WriteContractInput(
    address: String,
    functionName: String,
    args: List<Any>,
    abi: List<Map<String, Any>>
)
```

### GenericNetwork

```kotlin theme={"system"}
network.name            // String
network.chainId         // For EVM networks
network.networkId       // For Solana networks
```

## Error Handling

All SDK functions can throw exceptions. Use Kotlin's native error handling:

```kotlin theme={"system"}
try {
    sdk.auth.email.verifyOTP(code)
} catch (e: Exception) {
    Log.e("Auth", "Error: ${e.message}")
}
```

For coroutine-based code:

```kotlin theme={"system"}
viewModelScope.launch {
    try {
        sdk.auth.email.sendOTP(email)
    } catch (e: Exception) {
        errorMessage.value = "Failed: ${e.message}"
    }
}
```

## Quick Reference Example

```kotlin theme={"system"}
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.DynamicSDKConfig
import android.app.Application

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        DynamicSDK.initialize(
            context = applicationContext,
            config = DynamicSDKConfig(
                environmentId = "YOUR_ENV_ID"
            )
        )
    }
}

// In your MainActivity
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            MyApp()
        }
    }
}

@Composable
fun MyApp() {
    val sdk = DynamicSDK.getInstance()
    var isAuthenticated by remember {
        mutableStateOf(sdk.auth.authenticatedUser != null)
    }

    LaunchedEffect(Unit) {
        sdk.auth.authenticatedUserChanges.collect { user ->
            isAuthenticated = user != null
        }
    }

    if (isAuthenticated) {
        HomeScreen()
    } else {
        LoginScreen()
    }
}

@Composable
fun LoginScreen() {
    val sdk = DynamicSDK.getInstance()

    Button(onClick = { sdk.ui.showAuth() }) {
        Text("Sign In")
    }
}

@Composable
fun HomeScreen() {
    val sdk = DynamicSDK.getInstance()

    Column {
        Text("Welcome!")

        Button(onClick = { sdk.ui.showUserProfile() }) {
            Text("View Profile")
        }

        Button(onClick = {
            try {
                sdk.auth.logout()
            } catch (e: Exception) {
                Log.e("Home", "Logout failed: ${e.message}")
            }
        }) {
            Text("Logout")
        }
    }
}
```

## Session State Management with ViewModel

For production apps, use a ViewModel for better state management:

```kotlin theme={"system"}
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class SessionViewModel : ViewModel() {
    private val sdk = DynamicSDK.getInstance()

    private val _isAuthenticated = MutableStateFlow(
        sdk.auth.authenticatedUser != null
    )
    val isAuthenticated: StateFlow<Boolean> = _isAuthenticated.asStateFlow()

    init {
        // Observe authentication changes
        viewModelScope.launch {
            sdk.auth.authenticatedUserChanges.collect { user ->
                _isAuthenticated.value = user != null
            }
        }
    }

    fun logout() {
        viewModelScope.launch {
            try {
                sdk.auth.logout()
            } catch (e: Exception) {
                Log.e("SessionVM", "Logout failed: ${e.message}")
            }
        }
    }
}

// Use in Compose
@Composable
fun AppContent() {
    val viewModel: SessionViewModel = viewModel()
    val isAuthenticated by viewModel.isAuthenticated.collectAsState()

    if (isAuthenticated) {
        HomeScreen()
    } else {
        LoginScreen()
    }
}
```

<Tip>
  **Complete Example App**: For a fully functional Android app demonstrating all SDK
  features, check the Screens directory in the documentation repository for complete
  implementation examples.
</Tip>
