> For the complete documentation index, see [llms.txt](/llms.txt).

# Embedded Wallet SDK for Android

## Overview

The Web3Auth by MetaMask, Embedded Wallet SDK provides authentication for Android applications with social sign-in, external wallets, and more. Our Android SDK, written in Kotlin, simplifies how you connect users to their preferred wallets and manage authentication state natively.

## Requirements

- Android API version `26` or newer
- Android Compile and Target SDK: `34`
- Basic knowledge of Java or Kotlin development

## Prerequisites

- Set up your project on the [Embedded Wallets dashboard](https://developer.metamask.io/).

tip

See the [dashboard setup](/embedded-wallets/dashboard/) guide to learn more.

## Installation

Install the Web3Auth Android SDK by adding it to your project dependencies:

### 1. Add JitPack repository

In your project-level Gradle file add JitPack repository:

```groovy
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url "https://jitpack.io" } // <-- Add this line
    }
}

```

### 2. Add Web3Auth dependency

Then, in your app-level `build.gradle` dependencies section, add the following:

```groovy
dependencies {
    // ...
    implementation 'com.github.web3auth:web3auth-android-sdk:11.0.1'
}

```

2.1. Update permissions

Open your app's `AndroidManifest.xml` file and add the following permission. Ensure the `<uses-permission>` element is a direct child of the `<manifest>` root element.

```xml
<uses-permission android:name="android.permission.INTERNET" />

```

2.2 Configure `AndroidManifest.xml` File

Ensure your main activity `launchMode` is set to `singleTop` in your `AndroidManifest.xml`:

```xml
<activity
  android:launchMode="singleTop"
  android:name=".YourActivity">
  // ...
</activity>

```

From version **7.1.2**, set `android:allowBackup` to `false` and add `tools:replace="android:fullBackupContent"` in your `AndroidManifest.xml` file:

```xml
<application
        android:allowBackup="false"
        tools:replace="android:fullBackupContent"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher">
</application>

```

### 3. Handle redirects

Once the Gradle files and permissions have been updated, you need to configure your Embedded Wallets project by allowlisting your scheme and package name.

#### Configure a Plug n Play project

- From the [Embedded Wallets dashboard](https://developer.metamask.io), create or open an existing Web3Auth project.
- Allowlist `{SCHEME}://{YOUR_APP_PACKAGE_NAME}` in the dashboard. This step is mandatory for the redirect to work.

#### Configure deep link

Open your app's `AndroidManifest.xml` file and add the following deep link intent filter to your main activity:

```xml
<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="{scheme}" android:host="{YOUR_APP_PACKAGE_NAME}"/>
  <!-- Accept URIs: w3a://com.example.w3aflutter -->
</intent-filter>

```

### 4. Triggering sign-in exceptions

note

The Android SDK uses the custom tabs and from current implementation of Chrome custom tab, it's not possible to add a listener directly to Chrome custom tab close button and trigger sign-in exceptions.

Apply the `setCustomTabsClosed` method in your sign-in screen to trigger sign-in exceptions for Android.

```kotlin
class MainActivity : AppCompatActivity() {
    // Additional code

    override fun onResume() {
        super.onResume()
        if (Web3Auth.getCustomTabsClosed()) {
            Toast.makeText(this, "User closed the browser.", Toast.LENGTH_SHORT).show()
            web3Auth.setResultUrl(null)
            Web3Auth.setCustomTabsClosed(false)
        }
    }

    // Additional code
}

```

## Initialize Embedded Wallets

### 1. Create an Embedded Wallets instance

Create an Embedded Wallets instance and configure it with your project settings:

```kotlin
import com.web3auth.core.Web3Auth
import com.web3auth.core.types.Web3AuthOptions
import org.torusresearch.fetchnodedetails.types.Web3AuthNetwork

var web3Auth = Web3Auth(
  Web3AuthOptions(
    clientId = "YOUR_WEB3AUTH_CLIENT_ID", // Pass over your Web3Auth Client ID from Developer Dashboard
    web3AuthNetwork = Web3AuthNetwork.SAPPHIRE_MAINNET, // or Web3AuthNetwork.SAPPHIRE_DEVNET
    redirectUrl = "{YOUR_APP_PACKAGE_NAME}://auth",
  ),
  this
)

// Handle user signing in when app is in background
web3Auth.setResultUrl(intent?.data)

```

### 2. Set result URL

Whenever user initiates a sign-in flow, a new intent of CustomTabs is launched. It's necessary step to use `setResultUrl` in `onNewIntent` method to successful track the sign-in process.

```kotlin
override fun onNewIntent(intent: Intent?) {
  super.onNewIntent(intent)

  // Handle user signing in when app is active
  web3Auth.setResultUrl(intent.data)
}

```

### 3. Initialize the Embedded Wallets instance

After instantiating Embedded Wallets, call the `initialize` method. This method fetches your project configuration from the dashboard (whitelabel, chains, MFA settings, and session time) and restores any existing session.

`initialize` completes successfully only when it restores an active session. If there is no saved session, or the saved session is invalid or expired, the returned `CompletableFuture` completes exceptionally and the SDK clears the stored session data. It also completes exceptionally if fetching the project configuration fails.

note

A failed `initialize` call usually means the user isn't signed in. Show your sign-in screen in the error branch. If you need to distinguish the cases, the no-session error message is `No user found, please login again!`.

```kotlin
val initializeCF: CompletableFuture<Void> = web3Auth.initialize()
initializeCF.whenComplete { _, error ->
  if (error == null) {
    // Active session restored
    val privateKey = web3Auth.getPrivateKey()
  } else {
    // No active session, or initialization failed. Show the sign-in screen.
    Log.d("MainActivity_Web3Auth", error.message ?: "Something went wrong")
  }
}

```

## Advanced configuration

The Web3Auth Android SDK offers a rich set of advanced configuration options:

- **[Custom authentication](/embedded-wallets/sdk/android/advanced/custom-authentication/):** Define authentication methods.
- **[Whitelabeling and UI customization](/embedded-wallets/sdk/android/advanced/whitelabel/):** Personalize the modal's appearance.
- **[Multi-Factor Authentication (MFA)](/embedded-wallets/sdk/android/advanced/mfa/):** Set up and manage MFA.
- **[Dapp Share](/embedded-wallets/sdk/android/advanced/dapp-share/):** Share dapp sessions across devices.

tip

See the [advanced configuration sections](/embedded-wallets/sdk/android/advanced/) to learn more about each configuration option.

**Basic Configuration**

```kotlin
val web3Auth = Web3Auth(
    Web3AuthOptions(
        clientId = "YOUR_CLIENT_ID",
        web3AuthNetwork = Web3AuthNetwork.SAPPHIRE_MAINNET, // or Web3AuthNetwork.SAPPHIRE_DEVNET
        redirectUrl = "YOUR_APP_SCHEME://auth"
    ),
    this
)

```

**Advanced Configuration**

```kotlin
val web3Auth = Web3Auth(
    Web3AuthOptions(
        clientId = "YOUR_CLIENT_ID",
        web3AuthNetwork = Web3AuthNetwork.SAPPHIRE_MAINNET, // or Web3AuthNetwork.SAPPHIRE_DEVNET
        redirectUrl = "YOUR_APP_SCHEME://auth",
        authConnectionConfig = listOf(AuthConnectionConfig(
          authConnectionId = "auth-connection-id", // Get it from MetaMask Developer Dashboard
          authConnection = AuthConnection.GOOGLE,
          clientId = getString(R.string.google_client_id) // Google's client id
        )),
        mfaSettings = MfaSettings(
          deviceShareFactor = MfaSetting(true, 1, true),
          socialBackupFactor = MfaSetting(true, 2, true),
          passwordFactor = MfaSetting(true, 3, false),
          backUpShareFactor = MfaSetting(true, 4, false),
          passkeysFactor = MfaSetting(true, 5, true),
          authenticatorFactor = MfaSetting(true, 6, true),
        )
    ),
    this
)

```

## Single Factor Auth (SFA) Support

Web3Auth Android SDK includes built-in support for Single Factor Auth (SFA), allowing for seamless authentication when you already have a JWT token from your authentication system. Users are authenticated using just your JWT token, without a browser sign-in flow.

```kotlin
// SFA sign-in with custom JWT
val loginCompletableFuture = web3Auth.connectTo(
    LoginParams(
        AuthConnection.CUSTOM,
        authConnectionId = "your_auth_connection_id",
        idToken = "your_jwt_token"
    )
)

```

SFA mode is automatically activated when you provide an `idToken` parameter. This enables direct authentication without additional social sign-in steps, perfect for applications that already have their own authentication system.

SFA limitations

- `connectTo` in SFA mode retrieves key shares with blocking network calls on the calling thread. Call it from a background thread (for example, `Dispatchers.IO` or an `Executor`), not the main thread.
- If the user has already enabled MFA, SFA sign-in fails with `User has already enabled MFA`. Sign these users in through the browser flow instead, by passing the JWT as `extraLoginOptions = ExtraLoginOptions(id_token = jwt)` without setting `idToken`.
- `enableMFA()` and `manageMFA()` aren't available for SFA sessions and fail with `Enabling MFA is not allowed for this user.`
- SFA sessions are stored in the session service, not as Auth tokens. `getAccessToken()` and `getIdentityToken()` aren't available for SFA sessions.

## Blockchain Integration

Embedded Wallets is blockchain agnostic, enabling integration with any blockchain network. Out of the box, Embedded Wallets offers robust support for both **Solana** and **Ethereum**.

### Ethereum integration

For Ethereum integration, you can get the private key using the `getPrivateKey` method and use it with web3j or other Ethereum libraries:

```kotlin
import org.web3j.crypto.Credentials
import org.web3j.protocol.core.DefaultBlockParameterName
import org.web3j.protocol.Web3j
import org.web3j.protocol.http.HttpService

// Use your Web3Auth instance to get the private key
val privateKey = web3Auth.getPrivateKey()

// Generate the Credentials
val credentials = Credentials.create(privateKey)

// Get the address
val address = credentials.address

// Create the Web3j instance using your RPC URL
val web3 = Web3j.build(HttpService("YOUR_RPC_URL"))

// Get the balance
val balanceResponse = web3.ethGetBalance(address, DefaultBlockParameterName.LATEST).send()

// Convert the balance from Wei to Ether format
val ethBalance = BigDecimal.valueOf(balanceResponse.balance.toDouble()).divide(BigDecimal.TEN.pow(18))

```

### Solana integration

For Solana integration, you can get the Ed25519 private key using the `getEd25519PrivateKey` method and use it with sol4k or any other Solana libraries:

```kotlin
import org.sol4k.Connection
import org.sol4k.Keypair

val connection = Connection(RpcUrl.DEVNET)

// Use your Web3Auth instance to get the private key
val ed25519PrivateKey = web3Auth.getEd25519PrivateKey()

// Generate the Solana KeyPair
val solanaKeyPair = Keypair.fromSecretKey(ed25519PrivateKey.hexToByteArray())

// Get the user's public key
val publicKey = solanaKeyPair.publicKey.toBase58()

// Get the user balance
val userBalance = connection.getBalance(publicKey).toBigDecimal()

```
