📱 Complete Example App: For a fully functional Android app demonstrating all SDK
features, check out our Android SDK Example App. It
includes authentication flows (email/SMS OTP, social login, passkeys), wallet management, EVM/Solana transactions,
MFA, and passkey examples with Jetpack Compose.
- Agent-friendly
- Step-by-step
Add the Dynamic docs MCP to your AI editor first — your agent can then query the docs directly. Instructions are on the Welcome page.
# Kotlin SDK Quickstart
## Purpose and Usage
This document provides structured quickstart information for the Dynamic Kotlin SDK (Android). It is designed to be consumed by LLMs to generate accurate installation commands and code examples based on user requirements.
> **Important scope note:** The Dynamic Kotlin SDK is for **Android native apps** using Jetpack Compose. It provides embedded wallets, authentication (email OTP, SMS OTP, social login, passkeys), and multi-chain support (EVM + Solana). It uses AAR files — there is no Maven Central publication yet.
---
## How to use this document
Start by asking the user which path they want:
> "Would you like a **Quick start** (EVM only, Jetpack Compose, zero configuration — recommended if you're just getting started) or a **Custom setup** (choose your chains and configuration)?"
- If the user chooses **Quick start**: follow the Quick Start Path section exactly. Do not ask any configuration questions — execute the happy path as written.
- If the user chooses **Custom setup**: follow the Custom Setup Path section and ask all configuration questions before proceeding.
---
## Quick Start Path
> Use this path when the user chooses Quick start. Execute every step in order. Do not skip steps. Do not ask configuration questions.
**Stack:** Kotlin + Jetpack Compose + EVM only
### Step 1 — Prerequisites
Tell the user:
- Android SDK 28+ (Android 9.0+) is required
- Kotlin 2.1.0+ is required
- Gradle 8.x+ is required
- Java 17 is required
- A Dynamic environment ID is required — get it at https://app.dynamic.xyz/dashboard/overview
Ask the user for their environment ID before proceeding.
### Step 2 — Download AAR files
Download the latest AAR files from https://github.com/dynamic-labs/android-sdk-and-sample-app:
- `dynamic-sdk-android.aar` (required)
Place it in `app/libs/`.
### Step 3 — Add dependencies
Add to `build.gradle.kts`:
```kotlin
dependencies {
// Dynamic SDK AAR
implementation(files("libs/dynamic-sdk-android.aar"))
// Required transitive dependencies
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation("androidx.webkit:webkit:1.8.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("androidx.browser:browser:1.7.0")
implementation("androidx.datastore:datastore-preferences:1.1.1")
implementation("com.google.crypto.tink:tink-android:1.15.0")
implementation("androidx.credentials:credentials:1.2.2")
implementation("androidx.credentials:credentials-play-services-auth:1.2.2")
implementation("com.google.android.gms:play-services-auth:20.7.0")
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
}
```
### Step 4 — Configure AndroidManifest.xml
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application android:usesCleartextTraffic="true" ...>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- OAuth Callback Activity (Required) -->
<activity
android:name="com.dynamic.sdk.android.Auth.AuthCallbackActivity"
android:exported="true"
android:launchMode="singleTop"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourappscheme" />
</intent-filter>
</activity>
</application>
</manifest>
```
> The `android:scheme` must match the `redirectUrl` in `ClientProps`. For example, if `redirectUrl = "myapp://"`, use `android:scheme="myapp"`.
### Step 5 — Initialize the SDK
```kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.ui.Modifier
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.UI.DynamicUI
import com.dynamic.sdk.android.core.ClientProps
import com.dynamic.sdk.android.core.LoggerLevel
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val props = ClientProps(
environmentId = "your-environment-id",
appLogoUrl = "https://your-app.com/logo.png",
appName = "Your App Name",
redirectUrl = "yourappscheme://",
appOrigin = "https://your-app.com",
logLevel = LoggerLevel.DEBUG
)
DynamicSDK.initialize(props, applicationContext, this)
setContent {
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Box(modifier = Modifier.fillMaxSize()) {
AppContent()
DynamicUI() // Required overlay for auth flows
}
}
}
}
}
}
```
### Step 6 — Show the auth UI
```kotlin
import androidx.compose.material3.*
import androidx.compose.runtime.*
import com.dynamic.sdk.android.DynamicSDK
@Composable
fun LoginScreen() {
val sdk = DynamicSDK.getInstance()
Button(onClick = { sdk.ui.showAuth() }) {
Text("Sign In")
}
}
```
### Step 7 — Listen for auth state changes
```kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.UserProfile
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class AuthViewModel : ViewModel() {
private val sdk = DynamicSDK.getInstance()
private val _user = MutableStateFlow<UserProfile?>(null)
val user: StateFlow<UserProfile?> = _user
private val _isAuthenticated = MutableStateFlow(false)
val isAuthenticated: StateFlow<Boolean> = _isAuthenticated
init {
_isAuthenticated.value = sdk.auth.isAuthenticated()
_user.value = sdk.auth.authenticatedUser
viewModelScope.launch {
sdk.auth.authenticatedUserChanges.collect { user ->
_user.value = user
_isAuthenticated.value = user != null
}
}
}
}
```
### Step 8 — Enable features in dashboard
Tell the user:
1. Go to https://app.dynamic.xyz/dashboard/overview
2. Go to **Authentication** and enable Email OTP
3. Go to **Wallets** and enable embedded wallets
4. Go to **Chains** and enable an EVM testnet (e.g. Base Sepolia)
---
## Custom Setup Path
> Use this path when the user chooses Custom setup. Ask ALL questions below before generating any code.
**Questions to ask the user:**
1. Which chains do you need? (EVM only / EVM + Solana)
2. What is your app's URL scheme for OAuth callbacks? (e.g. `myapp://`)
3. What authentication methods do you want? (Email OTP, SMS OTP, Social login, Passkeys)
4. Do you need WalletConnect support for connecting to dApps?
### Configuration differences
**Solana support:** Add these extra dependencies:
```kotlin
implementation(files("libs/solana-web3.aar"))
implementation("org.sol4k:sol4k:0.6.0")
```
**WalletConnect support:** Add `reownProjectId` to `ClientProps`:
```kotlin
val props = ClientProps(
environmentId = "your-environment-id",
appLogoUrl = "https://your-app.com/logo.png",
appName = "Your App Name",
redirectUrl = "yourappscheme://",
appOrigin = "https://your-app.com",
reownProjectId = "your-reown-project-id"
)
```
### SDK Access (after initialization)
```kotlin
val sdk = DynamicSDK.getInstance()
// Auth
sdk.ui.showAuth()
sdk.auth.isAuthenticated()
sdk.auth.authenticatedUser
// Wallets
sdk.wallets.userWallets
sdk.wallets.primaryWallet
// User profile
sdk.ui.showUserProfile()
// Logout
sdk.auth.logout() // suspend function — call from a coroutine
```
### Wallet display example
```kotlin
import com.dynamic.sdk.android.Models.BaseWallet
import kotlinx.coroutines.flow.MutableStateFlow
class HomeViewModel : ViewModel() {
private val sdk = DynamicSDK.getInstance()
private val _wallets = MutableStateFlow<List<BaseWallet>>(emptyList())
val wallets: StateFlow<List<BaseWallet>> = _wallets
init {
_wallets.value = sdk.wallets.userWallets
viewModelScope.launch {
sdk.wallets.userWalletsChanges.collect { newWallets ->
_wallets.value = newWallets
}
}
}
}
```
---
## Critical Reference
| Correct | Incorrect | Notes |
|---|---|---|
| Place AAR in `app/libs/` | Reference a Maven coordinate | SDK is not on Maven Central |
| Call `DynamicSDK.initialize()` in `onCreate()` | Call `getInstance()` before `initialize()` | Throws if not initialized |
| Include `DynamicUI()` in root Compose layout | Omit `DynamicUI()` | Auth overlay won't appear |
| Match `android:scheme` to `redirectUrl` | Use different values | OAuth callbacks break |
| Use `viewModelScope.launch` for Flow collection | Collect on the main thread without lifecycle scope | Leaks coroutines |
| Whitelist deep link in Dynamic dashboard | Skip dashboard config | OAuth returns fail silently |
---
## Troubleshooting — Common Issues
### 1 — "Could not resolve: dynamic-sdk-android.aar"
Ensure the AAR file is in `app/libs/`. Clean the build (Build → Clean Project). Restart Android Studio.
### 2 — SDK not initialized
`DynamicSDK.initialize()` must be called in `MainActivity.onCreate()` before any views call `DynamicSDK.getInstance()`.
### 3 — OAuth callbacks not working
Verify the URL scheme in `AndroidManifest.xml` matches `redirectUrl` in `ClientProps`. Whitelist the deep link URL in the Dynamic dashboard under **Security → Whitelist Mobile Deeplink**.
### 4 — Wallets not appearing after login
Wallets are created asynchronously. Use `sdk.wallets.userWalletsChanges` Flow to listen for updates. Check that embedded wallets are enabled in the dashboard.
### 5 — DynamicUI overlay not showing
Ensure `DynamicUI()` is in your root Compose layout inside a `Box` or similar container that supports overlays.
If the issue persists, check https://docs.dynamic.xyz/overview/troubleshooting/general.
---
## Beyond This Quickstart
This prompt covers initial setup only. For deeper guides (authentication flows, wallet operations, session management, transactions, etc.), fetch the full documentation index:
**https://www.dynamic.xyz/docs/llms.txt**
This file contains every page in the Dynamic documentation organized by SDK. Search for the "Kotlin SDK" section to discover all available pages and their URLs. Use it as your navigation source for any question beyond what this quickstart covers.
Alternatively, if the Dynamic MCP server is available in your environment, query it directly for any documentation page.
Prerequisites
Prerequisites
Before you begin, make sure you have:
- Android SDK 28+ (Android 9.0+)
- Kotlin 2.1.0+
- Gradle 8.x+
- Java 17
- Dynamic Account — Environment ID from Dynamic Dashboard
Install the SDK
This guide uses AAR-based setup (there is no interactive embed on this page).Step 1: Download AAR files
Download the latest AAR files from the Dynamic Android SDK repository:dynamic-sdk-android.aar(required)solana-web3.aar(optional - only if you need Solana support)
app/libs directory.Step 2: Add dependencies
Add the Dynamic SDK and all required dependencies to yourbuild.gradle.kts:build.gradle.kts
dependencies {
// ==========================================
// Dynamic SDK AAR Files
// ==========================================
// Core SDK (required)
implementation(files("libs/dynamic-sdk-android.aar"))
// Solana SDK (optional - remove if not needed)
implementation(files("libs/solana-web3.aar"))
implementation("org.sol4k:sol4k:0.6.0") // Required by Dynamic Solana SDK
// ==========================================
// Required transitive dependencies
// ==========================================
// Kotlin Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
// JSON serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
// Android WebView
implementation("androidx.webkit:webkit:1.8.0")
// HTTP client
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Custom Tabs for authentication
implementation("androidx.browser:browser:1.7.0")
// Secure storage - DataStore + Tink
implementation("androidx.datastore:datastore-preferences:1.1.1")
implementation("com.google.crypto.tink:tink-android:1.15.0")
// Passkeys support
implementation("androidx.credentials:credentials:1.2.2")
implementation("androidx.credentials:credentials-play-services-auth:1.2.2")
implementation("com.google.android.gms:play-services-auth:20.7.0")
// Jetpack Compose (required for DynamicUI)
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
}
If you don’t need Solana support, you can skip the
solana-web3.aar and sol4k dependencies.Configure AndroidManifest.xml
Add the required permissions and activities to yourAndroidManifest.xml:AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:usesCleartextTraffic="true"
...>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- OAuth Callback Activity (Required) -->
<activity
android:name="com.dynamic.sdk.android.Auth.AuthCallbackActivity"
android:exported="true"
android:launchMode="singleTop"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourappscheme" />
</intent-filter>
</activity>
</application>
</manifest>
Make sure the
android:scheme in your manifest matches the redirectUrl in your ClientProps. For example, if redirectUrl = "myapp://", then use android:scheme="myapp".Initialize the SDK
Initialize the Dynamic SDK in your MainActivity:MainActivity.kt
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.ui.Modifier
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.UI.DynamicUI
import com.dynamic.sdk.android.core.ClientProps
import com.dynamic.sdk.android.core.LoggerLevel
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize Dynamic SDK
val props = ClientProps(
environmentId = "your-environment-id",
appLogoUrl = "https://your-app.com/logo.png",
appName = "Your App Name",
redirectUrl = "yourappscheme://",
appOrigin = "https://your-app.com",
logLevel = LoggerLevel.DEBUG
)
DynamicSDK.initialize(props, applicationContext, this)
setContent {
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Box(modifier = Modifier.fillMaxSize()) {
// Main app content
AppContent()
// Dynamic SDK WebView overlay (required for auth flows)
DynamicUI()
}
}
}
}
}
}
Configuration Options
TheClientProps supports various configuration options:| Property | Description | Required |
|---|---|---|
environmentId | Your Dynamic environment ID from the dashboard | Yes |
appName | Your app’s display name | Yes |
appLogoUrl | URL to your app’s logo (shown in auth UI) | Yes |
redirectUrl | Deep link URL scheme for OAuth callbacks | Yes |
appOrigin | Your app’s origin URL | Yes |
reownProjectId | Reown (WalletConnect) project ID for connecting to dApps | No |
logLevel | Logging level (.DEBUG, .INFO, .WARN, .ERROR) | No |
Access the SDK
After initialization, access the SDK singleton anywhere in your app:val sdk = DynamicSDK.getInstance()
// Show auth modal
sdk.ui.showAuth()
// Check auth state
val isAuthenticated = sdk.auth.isAuthenticated()
// Get wallets
val wallets = sdk.wallets.userWallets
// Get primary wallet
val primaryWallet = sdk.wallets.primaryWallet
Basic Usage
Using Built-in Authentication UI
The easiest way to add authentication is using the built-in UI:import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.dynamic.sdk.android.DynamicSDK
@Composable
fun LoginScreen() {
val sdk = DynamicSDK.getInstance()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center
) {
Button(
onClick = { sdk.ui.showAuth() },
modifier = Modifier.fillMaxWidth()
) {
Text("Sign In")
}
}
}
Listening for Authentication State
Use Kotlin Flow to react to authentication changes:import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.UserProfile
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class AuthViewModel : ViewModel() {
private val sdk = DynamicSDK.getInstance()
private val _user = MutableStateFlow<UserProfile?>(null)
val user: StateFlow<UserProfile?> = _user
private val _isAuthenticated = MutableStateFlow(false)
val isAuthenticated: StateFlow<Boolean> = _isAuthenticated
init {
// Check initial auth state
_isAuthenticated.value = sdk.auth.isAuthenticated()
_user.value = sdk.auth.authenticatedUser
// Listen for auth state changes
viewModelScope.launch {
sdk.auth.authenticatedUserChanges.collect { user ->
_user.value = user
_isAuthenticated.value = user != null
}
}
}
}
@Composable
fun AppContent(viewModel: AuthViewModel) {
val isAuthenticated by viewModel.isAuthenticated.collectAsState()
if (isAuthenticated) {
HomeScreen()
} else {
LoginScreen()
}
}
Complete Example with Wallets
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.BaseWallet
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
class HomeViewModel : ViewModel() {
private val sdk = DynamicSDK.getInstance()
private val _wallets = MutableStateFlow<List<BaseWallet>>(emptyList())
val wallets: StateFlow<List<BaseWallet>> = _wallets
init {
// Get current wallets
_wallets.value = sdk.wallets.userWallets
// Listen for wallet changes
viewModelScope.launch {
sdk.wallets.userWalletsChanges.collect { newWallets ->
_wallets.value = newWallets
}
}
}
fun showUserProfile() {
sdk.ui.showUserProfile()
}
fun logout() {
viewModelScope.launch {
sdk.auth.logout()
}
}
}
@Composable
fun HomeScreen(viewModel: HomeViewModel) {
val wallets by viewModel.wallets.collectAsState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
text = "Welcome!",
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(16.dp))
if (wallets.isEmpty()) {
CircularProgressIndicator()
Text("Creating wallets...")
} else {
LazyColumn {
items(wallets) { wallet ->
WalletCard(wallet)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = { viewModel.showUserProfile() },
modifier = Modifier.fillMaxWidth()
) {
Text("Show Profile")
}
Button(
onClick = { viewModel.logout() },
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.error
)
) {
Text("Logout")
}
}
}
@Composable
fun WalletCard(wallet: BaseWallet) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = wallet.chain.uppercase(),
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.primary
)
Text(
text = wallet.address,
style = MaterialTheme.typography.bodyMedium
)
}
}
}
Enable Features in Dashboard
Before you can use authentication and wallet features, enable them in your Dynamic dashboard:- Go to your Dynamic Dashboard
- Select your project
- Go to Authentication and enable the methods you want to use:
- Email OTP
- SMS OTP
- Social providers (Google, Apple, Farcaster, etc.)
- Passkeys
- Go to Wallets and enable embedded wallets
- Go to Chains and enable the networks you want to support (EVM and/or Solana)
For testing, we recommend starting with Email OTP authentication and an EVM
testnet like Base Sepolia. This gives you a complete setup without requiring
real phone numbers or mainnet transactions.
Troubleshooting
Common Issues
-
Could not resolve: dynamic-sdk-android.aar
- Make sure you’ve placed the AAR file in your
app/libsdirectory - Try cleaning the build (Build → Clean Project)
- Restart Android Studio
- Make sure you’ve placed the AAR file in your
-
SDK not initialized
- Ensure
DynamicSDK.initialize()is called in yourMainActivity.onCreate()before any views access the SDK - Don’t call
DynamicSDK.getInstance()before initialization
- Ensure
-
Authentication callbacks not working
- Verify your URL scheme is configured in
AndroidManifest.xml - Ensure the
redirectUrlmatches your URL scheme - Whitelist your deep link URL in the Dynamic dashboard under Security → Whitelist Mobile Deeplink
- Verify your URL scheme is configured in
-
Wallets not appearing after login
- Wallets are created asynchronously after authentication
- Use
sdk.wallets.userWalletsChangesFlow to listen for wallet updates - Check that embedded wallets are enabled in your dashboard
-
DynamicUI overlay not showing
- Make sure
DynamicUI()composable is included in your app’s root layout - Verify it’s placed inside a
Boxor similar container that allows overlays
- Make sure
Next Steps
Step-up authentication and device registration are required
before accepting the
2026_04_01 API version. You must implement
both manually in your headless integration.
See the upgrade guide.- Authentication Guide - Learn how to implement user authentication with email, SMS, and passkeys
- Social Authentication - Add social login options like Google, Apple, and Farcaster
- Session Management - Manage authentication state with Kotlin Flow
- Wallet Operations - Work with balances and sign messages
- EVM Operations - Perform EVM transactions
- Solana Operations - Send Solana transactions
- Connect to dApps - Use WalletConnect to connect your embedded wallet to any dApp
- Step-up authentication — required before accepting the
2026_04_01API version - Device registration — required before accepting the
2026_04_01API version
Building without DynamicUI()? See the Authentication screens for a full list of screens your app needs to handle.