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

# Embedded Wallets SDK for Flutter

## Overview

MetaMask Embedded Wallets SDK (formerly Web3Auth Plug and Play) provides social login authentication for Flutter applications. The Flutter SDK, written in Dart, helps you manage authentication state across both iOS and Android platforms. After sign-in, export the private key and use platform-native blockchain libraries such as web3dart or solana.

## Requirements

- **Android** API version 26 or newer, with `compileSdkVersion` 34
- **iOS** 14 or newer, Xcode 15+ and Swift 5.9+, with [Swift Package Manager](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers)enabled in Flutter (on by default in recent Flutter stable releases, such as 3.44)
- Basic knowledge of Dart and Flutter 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

To install the Web3Auth Flutter package, you have two options. You can either manually add the package in the `pubspec.yaml` file, or you can use the `flutter pub add` command.

### Add via pubspec.yaml

Add `web3auth_flutter` as a dependency to your `pubspec.yaml`:

```yaml
dependencies:
  web3auth_flutter: ^8.0.0

```

### Add via Flutter pub add

Add `web3auth_flutter` using `flutter pub add` command:

```sh
flutter pub add web3auth_flutter

```

### 1. Android configuration

Once we have installed Web3Auth Flutter SDK, we also need to add the configuration for Android.

#### Update `compileSdkVersion`

For Android build `compileSdkVersion` needs to be `34`. Check your app module Gradle file in your project to change it:

```groovy
android {
    namespace "com.example.app_name"
    compileSdkVersion 34
   // ..
}

```

#### Add Embedded Wallets to Gradle

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
    }
}

```

#### Update permissions

Open your app's `AndroidManifest.xml` file and add the following permission. Please make sure the `<uses-permission>` element should be a direct child of the `<manifest>` root element:

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

```

#### 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>

```

#### Handle custom tabs

For Android, you need to handle custom tabs lifecycle to trigger login exceptions. The Android SDK uses chrome custom tabs, and it's not possible to add a listener directly to the chrome custom tab close button to trigger login exceptions.

```dart
class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }

  @override
  void didChangeAppLifecycleState(final AppLifecycleState state) {
    // This is important to trigger the user cancellation on Android.
    if (state == AppLifecycleState.resumed) {
      Web3AuthFlutter.setCustomTabsClosed();
    }
  }
}

```

### 2. iOS configuration

#### Set the iOS deployment target

The minimum iOS version is 14.0. Set the deployment target of the **Runner** target to 14.0 or later in Xcode. If your project has a `Podfile`, set the global platform there too:

```ruby
platform :ios, '14.0'

```

#### Enable Swift Package Manager

Starting with v8, `web3auth_flutter` resolves the native [Web3Auth Swift SDK](https://github.com/Web3Auth/web3auth-swift-sdk) (v13) through Swift Package Manager (SPM). The plugin's podspec no longer declares a CocoaPods `Web3Auth` dependency, so your iOS build must use SPM.

SPM is enabled by default in recent Flutter stable releases, such as Flutter 3.44. If you use an older Flutter version, or you turned SPM off, enable it:

```sh
flutter config --enable-swift-package-manager

```

Flutter adds the generated Swift package to your Xcode project automatically. See the [Flutter Swift Package Manager guide](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers)for details.

### 3. Configure redirects

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

## Initialize Web3Auth

### 1. Configure Web3Auth instance

Import and configure Web3Auth in your Flutter application:

main.dart

```dart
import 'package:web3auth_flutter/web3auth_flutter.dart';
import 'package:web3auth_flutter/enums.dart';
import 'package:web3auth_flutter/input.dart';
import 'package:web3auth_flutter/output.dart';
import 'dart:io';

Future<void> initWeb3Auth() async {
  late final String redirectUrl;

  if (Platform.isAndroid) {
    redirectUrl = 'w3a://com.example.w3aflutter';
    // w3a://com.example.w3aflutter
  } else {
    redirectUrl = 'com.example.w3aflutter://auth';
    // com.example.w3aflutter://auth
  }

  await Web3AuthFlutter.init(Web3AuthOptions(
    clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable // Get your Client ID from Embedded Wallets dashboard
    web3AuthNetwork: Web3AuthNetwork.sapphire_mainnet, // or Web3AuthNetwork.sapphire_devnet
    redirectUrl: redirectUrl,
    authBuildEnv: BuildEnv.production,
  ));
}

```

### 2. Initialize an Embedded Wallets instance

Initialize the Embedded Wallets instance and check for existing sessions:

```dart
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  String _result = '';
  bool logoutVisible = false;

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    await initWeb3Auth();

    try {
      // Restore an existing session. Throws when no active session is present.
      await Web3AuthFlutter.initialize();
    } catch (e) {
      print('No active session: $e');
    }

    final privateKey = await Web3AuthFlutter.getPrivateKey();
    if (privateKey.isNotEmpty) {
      setState(() {
        logoutVisible = true;
        _result = 'Existing session found';
      });
    }
  }
}

```

note

After configuring Embedded Wallets with `init`, call the `initialize` method to restore an existing session. On Android, `initialize` also fetches your project configuration from the dashboard. On iOS, `init` restores the session and `initialize` verifies that an authenticated session exists.

`initialize` throws when no active session is present (for example, on first launch or after `logout`). Wrap it in a `try`/`catch` block and treat the error as "user isn't signed in".

If the project configuration request fails, the error surfaces from `initialize` on Android, and from `init` on iOS as a `PlatformException` with the code `InitFailedException`.

## Advanced configuration

The Embedded Wallets Flutter SDK offers a rich set of advanced configuration options:

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

tip

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

**Basic Configuration**

```dart
await Web3AuthFlutter.init(Web3AuthOptions(
  clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable
  web3AuthNetwork: Web3AuthNetwork.sapphire_mainnet, // or Web3AuthNetwork.sapphire_devnet
  redirectUrl: redirectUrl,
));

```

**Advanced Configuration**

```dart
await Web3AuthFlutter.init(Web3AuthOptions(
  clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable
  web3AuthNetwork: Web3AuthNetwork.sapphire_mainnet,
  redirectUrl: redirectUrl,
  defaultChainId: "0x1",
  chains: [
    Chains(
      chainId: "0x1",
      rpcTarget: "https://rpc.ankr.com/eth",
      displayName: "Ethereum Mainnet",
      blockExplorerUrl: "https://etherscan.io",
      ticker: "ETH",
      tickerName: "Ethereum",
    ),
  ],
  mfaSettings: MfaSettings(
    deviceShareFactor: MfaSetting(
      enable: true,
      priority: 1,
    ),
    backUpShareFactor: MfaSetting(
      enable: true,
      priority: 2,
    ),
    socialBackupFactor: MfaSetting(
      enable: true,
      priority: 3,
    ),
    passwordFactor: MfaSetting(
      enable: true,
      priority: 4,
    ),
  ),
));

```

## Blockchain integration

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

### Ethereum integration

For Ethereum integration, you can get the private key and use it with web3dart or other Ethereum libraries:

```dart
import 'package:web3dart/web3dart.dart';

// Use your Web3Auth instance to get the private key
final privateKey = await Web3AuthFlutter.getPrivateKey();

// Generate the Credentials
final credentials = EthPrivateKey.fromHex(privateKey);

// Get the address
final address = credentials.address;

// Create the Web3Client instance using your RPC URL
final client = Web3Client("YOUR_RPC_URL", Client());

// Get the balance
final balanceResponse = await client.getBalance(address);

// Convert the balance to ether format, and round off to 4 decimal places.
final balance = balanceResponse.getValueInUnit(EtherUnit.ether).toStringAsFixed(4);

```

### Solana integration

For Solana integration, you can get the Ed25519 private key:

```dart
import 'dart:math';
import 'package:solana/solana.dart';
import 'package:web3auth_flutter/web3auth_flutter.dart';

// Use your Web3Auth instance to get the ED25519 private key
final privateKey = await Web3AuthFlutter.getEd25519PrivateKey();

// Generate the KeyPair
final keyPair = await Ed25519HDKeyPair.fromPrivateKeyBytes(
  privateKey: privateKey,
);

// Get the address
final address = keyPair.address;

// Create the SolanaClient instance using Solana RPC URL
final client = SolanaClient(
  rpcUrl: Uri.parse('https://api.devnet.solana.com'),
  websocketUrl: Uri.parse('ws://api.devnet.solana.com'),
);

// Get the balance
final balanceResponse = await client.rpcClient.getBalance(address);

// Convert the balance from lamports to SOL, and round off to 4 decimal places
final balance = (balanceResponse.value / pow(10, 9)).toStringAsFixed(4);


```
