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

# Embedded Wallets SDK for Flutter

## Overview[​](#overview "Direct link to Overview")

MetaMask Embedded Wallets SDK (formerly Web3Auth Plug and Play) provides a seamless authentication experience for Flutter applications with social logins, external wallets, and more. Our Flutter SDK, written in Dart, simplifies connecting users to their preferred wallets and manage authentication state across both iOS and Android platforms.

## Requirements[​](#requirements "Direct link to Requirements")

- **Android** API version 26 or newer
- **iOS** 14, Xcode 12+ and Swift 5.x
- Basic knowledge of Dart and Flutter Development

## Prerequisites[​](#prerequisites "Direct link to 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[​](#installation "Direct link to 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-via-pubspecyaml "Direct link to Add via pubspec.yaml")

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

```
dependencies:
  web3auth_flutter: ^6.1.2

```

### Add via Flutter pub add[​](#add-via-flutter-pub-add "Direct link to Add via Flutter pub add")

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

```
flutter pub add web3auth_flutter

```

### 1\. Android configuration[​](#1-android-configuration "Direct link to 1. Android configuration")

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

#### Update `compileSdkVersion`[​](#update-compilesdkversion "Direct link to update-compilesdkversion")

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

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

```

#### Add Embedded Wallets to Gradle[​](#add-embedded-wallets-to-gradle "Direct link to Add Embedded Wallets to Gradle")

In your project-level Gradle file add JitPack repository:

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

```

#### Update permissions[​](#update-permissions "Direct link to 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:

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

```

#### Configure deep link[​](#configure-deep-link "Direct link to Configure deep link")

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

```
<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[​](#handle-custom-tabs "Direct link to 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.

```
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[​](#2-ios-configuration "Direct link to 2. iOS configuration")

#### Update global iOS platform[​](#update-global-ios-platform "Direct link to Update global iOS platform")

For iOS build global platform needs to be 14.0. Check `Podfile` in your project to change the global platform:

```
platform :ios, '14.0'

```

### 3\. Configure redirects[​](#3-configure-redirects "Direct link to 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[​](#initialize-web3auth "Direct link to Initialize Web3Auth")

### 1\. Configure Web3Auth instance[​](#1-configure-web3auth-instance "Direct link to 1. Configure Web3Auth instance")

Import and configure Web3Auth in your Flutter application:

main.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 Uri redirectUrl;

  if (Platform.isAndroid) {
    redirectUrl = Uri.parse('{SCHEME}://{HOST}/auth');
    // w3a://com.example.w3aflutter/auth
  } else {
    redirectUrl = Uri.parse('{bundleId}://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
    network: Network.sapphire_mainnet, // or Network.sapphire_devnet
    redirectUrl: redirectUrl,
  ));
}

```

### 2\. Initialize an Embedded Wallets instance[​](#2-initialize-an-embedded-wallets-instance "Direct link to 2. Initialize an Embedded Wallets instance")

Initialize the Embedded Wallets instance and check for existing sessions:

```
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 {
      // Initialize and check for existing session
      await Web3AuthFlutter.initialize();
      final privateKey = await Web3AuthFlutter.getPrivKey();

      if (privateKey.isNotEmpty) {
        setState(() {
          logoutVisible = true;
          _result = 'Existing session found';
        });
      }
    } catch (e) {
      print('Error: $e');
    }
  }
}

```

note

After configuring Embedded Wallets, the next step is to initialize it using the `initialize` method. This method is essential for setting up the SDK, checking for any active sessions, and fetching the whitelabel configuration from your dashboard.

If the API call to fetch the project configuration fails, the method will throw an error.

## Advanced configuration[​](#advanced-configuration "Direct link to 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
- Advanced Configuration

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

```

```
await Web3AuthFlutter.init(Web3AuthOptions(
  clientId: "YOUR_WEB3AUTH_CLIENT_ID", // Pass your Web3Auth Client ID, ideally using an environment variable
  network: Network.sapphire_mainnet,
  redirectUrl: redirectUrl,
  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[​](#blockchain-integration "Direct link to 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[​](#ethereum-integration "Direct link to Ethereum integration")

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

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

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

// 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[​](#solana-integration "Direct link to Solana integration")

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

```
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.getED25519PrivKey();

// 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);


```
