Flutter SDK v8 Migration Guide
This guide upgrades Embedded Wallets Flutter SDK integrations from v3 through v7 directly to v8.
AI-assisted migration
For the best results, install the Web3Auth by MetaMask, Embedded Wallet SDK skill and MCP server before
you migrate.
See Build with AI for setup (npx skills add web3auth/skill and
MCP at https://mcp.web3auth.io).
Copy the prompt below into your AI coding assistant (Cursor, Claude Code, Codex, Antigravity, or similar):
Migrate my Embedded Wallet SDK for Flutter (web3auth_flutter) project to v8.
Before changing code:
1. Use the web3auth skill and MCP tools (search_docs, get_doc, get_example, get_sdk_reference).
2. Read the migration guide: https://docs.metamask.io/embedded-wallets/migration-guides/flutter/
3. Detect my current SDK version from pubspec.yaml and list which breaking changes apply.
Then migrate my codebase directly to v8:
- Update web3auth_flutter to ^8.0.0 in pubspec.yaml.
- Set Android minSdkVersion to 26 and compileSdkVersion to 34.
- Set the iOS deployment target to 14.0 or later and make sure Swift Package Manager is enabled;
v8 no longer pulls Web3Auth through CocoaPods:
- Remove any `enable-swift-package-manager: false` entry under `flutter: config:` in pubspec.yaml.
- Remove any manual pod 'Web3Auth' line from ios/Podfile.
- If SPM is off globally, run flutter config --enable-swift-package-manager.
- Run flutter clean, then pod deintegrate and pod install in ios/ to clear the old Web3Auth pod.
- Replace MFALevel.DEFAULT with MFALevel.OPTIONAL, MFALevel.MANDATORY, or MFALevel.NONE.
- Remove sessionTime from Web3AuthOptions unless I need a duration other than my dashboard setting (30 days if none is configured).
- Wrap Web3AuthFlutter.initialize(), getAccessToken(), getIdentityToken(), and refreshSession() in try/catch; they throw when no session is active.
- If I set WalletServicesConfig.confirmationStrategy, confirm it still behaves as expected (default and serialization changed in v8).
- If upgrading from v6 or earlier:
- Replace Web3AuthFlutter.login() with Web3AuthFlutter.connectTo().
- Replace Provider with AuthConnection and loginProvider with authConnection.
- Replace loginConfig (a HashMap<String, LoginConfigItem>) with authConnectionConfig (a List<AuthConnectionConfig>).
- Replace Network with Web3AuthNetwork and network: with web3AuthNetwork:.
- Replace redirectUrl: Uri with redirectUrl: String; it is now required on Web3AuthOptions, and LoginParams.redirectUrl is removed.
- Replace getPrivKey() with getPrivateKey() and getEd25519PrivKey() with getEd25519PrivateKey().
- Rename response.privKey, response.ed25519PrivKey, TorusUserInfo, and UserInfo fields per the guide's rename table.
- Replace launchWalletServices(ChainConfig) with showWalletUI() and move chains to Web3AuthOptions (Android uses only the first chain).
- Replace request(ChainConfig, method, params) with request(method, params), and read SignResponse.success, result, and error.
- Replace useCoreKitKey with useSFAKey, buildEnv with authBuildEnv, and move chainNamespace onto Chains.
- For Firebase and other JWT providers, pass idToken on LoginParams instead of extraLoginOptions.id_token.
- Remove any setResultUrl calls (removed in v4).
- Use Web3AuthFlutter.setCustomTabsClosed() on Android for sign-in cancellation handling.
- Do not change my Client ID, Sapphire network, or auth connection IDs unless I ask; that would change wallet addresses.
After migrating, list every file you changed and any manual dashboard steps I still need to do.
Use planning mode (where available) for the initial prompt. Review the plan before generating code; config mistakes can change wallet addresses in production.
Install v8
Update pubspec.yaml:
dependencies:
web3auth_flutter: ^8.0.0
Or run:
flutter pub add web3auth_flutter
Set Android minSdkVersion to 26 and compileSdkVersion to 34:
android {
compileSdkVersion 34
defaultConfig {
minSdkVersion 26
}
}
Set the iOS deployment target to 14.0 or later (the Runner target in Xcode, and
platform :ios in ios/Podfile if your project has one). The plugin and the native Swift SDK
declare iOS 14.0 as the minimum; the official v8 examples use 15.0. Make sure Swift Package Manager
is enabled; see iOS requires Swift Package Manager.
Add JitPack to your project-level Gradle file and configure platform redirects. See the Flutter SDK get started for Android and iOS setup.
v8 aligns with Android SDK v11 and iOS SDK v13 (Auth v11 and Wallet Services v6).
v8 breaking changes
iOS requires Swift Package Manager
v8 resolves the native 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.
If your build doesn't use SPM, iOS fails to find the Web3Auth module. To switch over:
-
Remove any per-project opt-out from
pubspec.yaml. The official v7 examples disabled SPM this way, and this setting overrides the global Flutter setting:flutter:config:# Remove this line:enable-swift-package-manager: false -
If you turned SPM off globally, enable it:
flutter config --enable-swift-package-manager -
Remove any manual
pod 'Web3Auth'line fromios/Podfile. -
Clear the old CocoaPods integration so the v7
Web3Authpod isn't reused:flutter cleancd iospod deintegratepod install
Building the Swift package requires Xcode 15 or later. See the Flutter Swift Package Manager guide.
MFALevel.DEFAULT removed
Auth v11 supports only optional, mandatory, and no MFA prompts.
Replace MFALevel.DEFAULT with MFALevel.OPTIONAL, MFALevel.MANDATORY, or MFALevel.NONE:
await Web3AuthFlutter.connectTo(
LoginParams(
authConnection: AuthConnection.google,
// v7: mfaLevel: MFALevel.DEFAULT,
mfaLevel: MFALevel.OPTIONAL,
),
);
sessionTime is now optional
Web3AuthOptions.sessionTime is now nullable. In v7, an unset sessionTime always sent 30 days.
In v8, when you don't set sessionTime, the native SDK uses the session time from your dashboard
project if you configured one, and 30 days otherwise. If you relied on the implicit 30-day
default, your session length now follows your dashboard setting. On iOS, values over 30 days are
capped at 30 days. Remove sessionTime from your options unless you need a duration other than
your dashboard setting.
initialize throws without an active session
Web3AuthFlutter.initialize() restores the session managed by the native SDKs.
On iOS, initialize was a no-op in v7. It now verifies that an authenticated session exists, and
throws when it doesn't.
On Android, initialize now fetches your project configuration and restores the auth session.
If restoring fails, it clears the stored session and throws.
Wrap the call in try/catch on both platforms:
await Web3AuthFlutter.init(options);
try {
await Web3AuthFlutter.initialize();
} catch (e) {
// No active session. Show your sign-in screen.
}
Service URL versions
The default service URLs moved to Auth v11, Wallet Services v6, and dashboard v11.
If you override sdkUrl, walletSdkUrl, or dashboardUrl in Web3AuthOptions, update them to
the matching versions, or remove the overrides to use the defaults.
BuildEnv.testing hosts remain unversioned.
storageServerUrl and sessionSocketUrl now default to the session service hosts for your
authBuildEnv instead of being sent as null. The new citadelServerUrl option also has a
default.
Wallet Services confirmation strategy
WalletServicesConfig.confirmationStrategy no longer defaults to
ConfirmationStrategy.defaultStrategy; it now defaults to null, so the native SDK default
applies.
Values are now serialized with native names: autoApprove sends auto-approve, and
defaultStrategy sends default. If you set confirmationStrategy, verify that wallet
confirmations still behave as you expect.
New APIs (non-breaking)
| API | Description |
|---|---|
Web3AuthFlutter.getAccessToken() | Returns the access token for the current auth session. |
Web3AuthFlutter.getIdentityToken() | Returns the identity token (ID token) for the current auth session. |
Web3AuthFlutter.refreshSession() | Refreshes the session and returns the updated Web3AuthResponse. |
Web3AuthFlutter.getUserInfoAsync() | Fetches user info asynchronously, and can backfill idToken from the session. |
LoginParams.recordId | Optional audit record ID for the sign-in request. The native SDK generates one when unset. |
LoginParams.loginSource | Audit login source. Defaults to web3auth-flutter. |
Web3AuthOptions.citadelServerUrl | Custom auth session service URL. |
Web3AuthOptions.wsEmbedDappClientId | Optional dapp client ID for the Wallet Services embed. |
Web3AuthOptions.useAAWithExternalWallet | Use account abstraction with external wallets. Comes from project configuration when unset. |
WhiteLabelData.tncLink, privacyPolicy | Terms and privacy policy URLs (plain String) shown in the consent UI. |
WalletServicesConfig.enableKeyExport | Controls private key export in the wallet UI. |
These methods throw when no authenticated session is present:
try {
final String accessToken = await Web3AuthFlutter.getAccessToken();
final String idToken = await Web3AuthFlutter.getIdentityToken();
final Web3AuthResponse refreshed = await Web3AuthFlutter.refreshSession();
} catch (e) {
// No active session. Show your sign-in screen.
}
See the Flutter SDK usage reference for details.
v7 breaking changes
Apply this section if you are upgrading from v6 or earlier. v7 aligned with Android SDK v10 and iOS SDK v12.
API renames
| v6 | v7 |
|---|---|
Network | Web3AuthNetwork |
network: | web3AuthNetwork: |
Provider / TypeOfLogin | AuthConnection |
Provider.jwt | AuthConnection.custom |
Web3AuthFlutter.login() | Web3AuthFlutter.connectTo() |
loginProvider: | authConnection: |
redirectUrl: Uri (optional) | redirectUrl: String (required) |
LoginParams.redirectUrl | Removed; set it on Web3AuthOptions |
loginConfig (HashMap) | authConnectionConfig (List) |
LoginConfigItem | AuthConnectionConfig |
verifier | authConnectionId |
verifierSubIdentifier | groupedAuthConnectionId |
verifierIdField | userIdField |
isVerifierIdCaseSensitive | isUserIdCaseSensitive |
getPrivKey() | getPrivateKey() |
getEd25519PrivKey() | getEd25519PrivateKey() |
TorusUserInfo | UserInfo |
userInfo.verifier | userInfo.authConnectionId |
userInfo.verifierId | userInfo.userId |
userInfo.typeOfLogin | userInfo.authConnection |
userInfo.aggregateVerifier | userInfo.groupedAuthConnectionId |
response.privKey | response.privateKey |
response.ed25519PrivKey | response.ed25519PrivateKey |
launchWalletServices(ChainConfig) | showWalletUI() |
request(ChainConfig, method, params) | request(method, params) |
SDK ChainConfig | Web3AuthOptions(chains: [Chains(...)]) |
Web3AuthOptions.chainNamespace | Chains.chainNamespace |
useCoreKitKey | useSFAKey |
buildEnv | authBuildEnv |
loginConfig was a HashMap<String, LoginConfigItem>. authConnectionConfig is a
List<AuthConnectionConfig>, so convert map entries to list items rather than renaming the
parameter. See Custom JWT and Firebase for an example.
Sign in with connectTo
final Web3AuthResponse response = await Web3AuthFlutter.connectTo(
LoginParams(authConnection: AuthConnection.google),
);
Custom JWT and Firebase
Pass the JWT on LoginParams.idToken with authConnectionId:
final Web3AuthResponse response = await Web3AuthFlutter.connectTo(
LoginParams(
authConnection: AuthConnection.custom,
authConnectionId: "w3a-firebase-demo",
idToken: firebaseIdToken,
),
);
Configure the connection during initialization:
authConnectionConfig: [
AuthConnectionConfig(
authConnection: AuthConnection.custom,
authConnectionId: "w3a-firebase-demo",
clientId: "WEB3AUTH_CLIENT_ID",
),
],
Wallet Services and signing
Configure chains in Web3AuthOptions, then call Wallet Services without a chain argument:
await Web3AuthFlutter.init(
Web3AuthOptions(
clientId: "WEB3AUTH_CLIENT_ID",
web3AuthNetwork: Web3AuthNetwork.sapphire_mainnet,
redirectUrl: redirectUrl,
chains: [
Chains(
chainId: "0x1",
rpcTarget: "https://mainnet.infura.io/v3/<YOUR_KEY>",
displayName: "Ethereum Mainnet",
ticker: "ETH",
),
],
defaultChainId: "0x1",
),
);
await Web3AuthFlutter.showWalletUI();
On Android, the plugin passes only the first entry in chains to the native SDK. Additional chains
in the list are ignored on Android.
request() returns a SignResponse with success, result, and error fields. Check success
before you use result:
try {
List<dynamic> params = [];
params.add("Hello, Web3Auth from Flutter!");
params.add("<User Address in Hex>");
final SignResponse response = await Web3AuthFlutter.request(
"personal_sign",
params,
);
if (response.success) {
log(response.result ?? "");
} else {
log(response.error ?? "Request failed");
}
} on PlatformException catch (e) {
log(e.message ?? e.toString());
}
Earlier breaking changes
Apply the sections below if you are upgrading from versions older than v6.
setResultUrl removed (from v4)
v4 removes setResultUrl.
v5 adds Web3AuthFlutter.setCustomTabsClosed(). On Android, call it in your app lifecycle
observer to detect when the user closes the custom tab:
void didChangeAppLifecycleState(final AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
Web3AuthFlutter.setCustomTabsClosed();
}
}
Register the observer in initState with WidgetsBinding.instance.addObserver(this).
v6 changes (if upgrading from v4-v5)
getSignResponse()removed: use the return value ofrequest().- Minimum Android SDK 26: update
minSdkVersionin your app-level Gradle file.
Summary table
| Area | v3 and earlier | v4-v5 | v6 | v7 | v8 |
|---|---|---|---|---|---|
setResultUrl | Used on Android | Removed | Removed | Removed | Removed |
| Sign result | N/A | getSignResponse() | Return value of request() | Return value of request() | Return value of request() |
| Sign in | login() | login() | login() | connectTo() | connectTo() |
| Private key | getPrivKey() | getPrivKey() | getPrivKey() | getPrivateKey() | getPrivateKey() |
| Wallet UI | N/A | launchWalletServices() | launchWalletServices() | showWalletUI() | showWalletUI() |
| Chain config | N/A | Per-method ChainConfig | Per-method ChainConfig | Web3AuthOptions.chains | Web3AuthOptions.chains |
| Session tokens | N/A | N/A | N/A | N/A | getAccessToken(), getIdentityToken() |
| Android minSdk | 24 | 24 | 26 | 26 | 26 |
| iOS native SDK | CocoaPods | CocoaPods | CocoaPods | CocoaPods (SPM from 7.0.1) | SPM only |
MFALevel.DEFAULT | Available | Available | Available | Available | Removed |
Next steps
- Flutter SDK get started
- Build with AI for ongoing integration help
- Release notes