This example demonstrates how to integrate MetaMask Embedded Wallets with Auth0 authentication in a Flutter application. It showcases a custom authentication setup using Auth0 as the identity provider with Web3Auth's blockchain functionality.
- Auth0 Social Logins: Google, Facebook, Twitter, GitHub, and more
- Universal Login: Auth0's hosted login page with customization options
- Custom JWT Authentication: Auth0 ID tokens used for Web3Auth login
- EVM Wallet: Automatic Ethereum wallet creation linked to Auth0 identity
- Blockchain Interactions: Full blockchain operations using web3dart
- Secure Key Management: Non-custodial key management with Auth0 identity
- Cross-Platform: Single codebase for iOS and Android
- Enterprise-Ready: Auth0's enterprise features (SSO, MFA, etc.)
- Flutter: 3.0.0 or higher
- Dart: 2.18.0 or higher
- Auth0 Account: Create one here
- MetaMask Embedded Wallets: Dashboard account
- iOS (for iOS development):
- iOS 14+, Xcode 12+, Swift 5.x, CocoaPods
- Android (for Android development):
- API level 26+, compileSdkVersion 34, JDK 11+
-
Clone the repository:
git clone https://github.com/Web3Auth/web3auth-flutter-examples.git cd web3auth-flutter-examples/flutter-auth0-example -
Install dependencies:
flutter pub get
-
iOS Setup (for iOS development):
cd ios && pod install && cd ..
-
Create an Auth0 Application:
- Go to Auth0 Dashboard
- Create a new application β Native
- Note your Domain and Client ID
-
Configure Allowed Callback URLs:
- Add for iOS:
com.example.auth0app://YOUR_AUTH0_DOMAIN/ios/com.example.auth0app/callback - Add for Android:
com.example.auth0app://YOUR_AUTH0_DOMAIN/android/com.example.auth0app/callback
- Add for iOS:
-
Configure Allowed Logout URLs:
- Add for iOS:
com.example.auth0app://YOUR_AUTH0_DOMAIN/ios/com.example.auth0app/logout - Add for Android:
com.example.auth0app://YOUR_AUTH0_DOMAIN/android/com.example.auth0app/logout
- Add for iOS:
-
Enable social connections (optional):
- Go to Authentication β Social
- Enable and configure providers (Google, Facebook, etc.)
-
Create a project on the Embedded Wallets Dashboard
-
Choose your network:
- Sapphire Devnet: For development/testing
- Sapphire Mainnet: For production
-
Create a Custom Authentication connection:
- Go to "Auth" β "Custom Authentication"
- Click "Create Verifier"
- Configure Auth0:
- Verifier Name: Give it a unique name (e.g.,
auth0-flutter-verifier) - Login Provider: Select "Auth0"
- Auth0 Domain: Your Auth0 domain (e.g.,
your-tenant.us.auth0.com) - Auth0 Client ID: Your Auth0 application client ID
- JWT Verifier ID:
sub(Auth0 user ID) - JWK Endpoint: Auto-filled as
https://YOUR_DOMAIN/.well-known/jwks.json
- Verifier Name: Give it a unique name (e.g.,
-
Configure platform settings:
- iOS: Allowlist
{bundleId}://auth - Android: Allowlist your package name
- iOS: Allowlist
-
Get your Client ID and Verifier Name from the dashboard
Update the configuration in lib/config/auth0_config.dart:
class Auth0Config {
static const String domain = "your-tenant.us.auth0.com";
static const String clientId = "YOUR_AUTH0_CLIENT_ID";
// Redirect URLs
static String getCallbackUrl(String bundleId) {
if (Platform.isAndroid) {
return "$bundleId://$domain/android/$bundleId/callback";
} else if (Platform.isIOS) {
return "$bundleId://$domain/ios/$bundleId/callback";
}
throw UnsupportedError('Unsupported platform');
}
}Update Web3Auth configuration in lib/main.dart:
import 'package:web3auth_flutter/web3auth_flutter.dart';
Future<void> initWeb3Auth() async {
late final Uri redirectUrl;
if (Platform.isAndroid) {
redirectUrl = Uri.parse('w3a://com.example.auth0app/auth');
} else if (Platform.isIOS) {
redirectUrl = Uri.parse('com.example.auth0app://auth');
}
await Web3AuthFlutter.init(
Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
network: Network.sapphire_mainnet,
redirectUrl: redirectUrl,
)
);
await Web3AuthFlutter.initialize();
}# Run in debug mode
flutter run
# Build for release
flutter build ios # For iOS
flutter build apk # For Androidlib/
βββ main.dart # Entry point & initialization
βββ config/
β βββ auth0_config.dart # Auth0 configuration
βββ services/
β βββ auth0_service.dart # Auth0 authentication
β βββ web3auth_service.dart # Web3Auth operations
β βββ blockchain.dart # Blockchain operations
βββ screens/
βββ home.dart # Home screen with wallet info
βββ login.dart # Login screen
import 'package:auth0_flutter/auth0_flutter.dart';
import 'package:web3auth_flutter/web3auth_flutter.dart';
// Initialize Auth0
final auth0 = Auth0(
Auth0Config.domain,
Auth0Config.clientId,
);
// Initialize Web3Auth
Future<void> initWeb3Auth() async {
// ... (see Code Configuration section above)
}import 'package:auth0_flutter/auth0_flutter.dart';
Future<void> loginWithAuth0() async {
try {
// Step 1: Login with Auth0
final credentials = await auth0.webAuthentication().login(
useEphemeralSession: true, // Don't persist session in browser
);
// Step 2: Get ID Token
final idToken = credentials.idToken;
// Step 3: Login to Web3Auth with Auth0 JWT
final Web3AuthResponse response = await Web3AuthFlutter.login(
LoginParams(
loginProvider: Provider.jwt,
extraLoginOptions: ExtraLoginOptions(
id_token: idToken,
verifierIdField: 'sub',
domain: Auth0Config.domain,
),
)
);
print('Web3Auth login successful!');
print('User: ${response.userInfo?.email}');
} on WebAuthenticationException catch (e) {
print('Auth0 error: ${e.message}');
} catch (e) {
print('Login error: $e');
}
}Future<void> loginWithGoogle() async {
try {
// Login with specific social connection
final credentials = await auth0.webAuthentication().login(
parameters: {
'connection': 'google-oauth2', // Or 'facebook', 'github', etc.
},
);
final idToken = credentials.idToken;
await Web3AuthFlutter.login(
LoginParams(
loginProvider: Provider.jwt,
extraLoginOptions: ExtraLoginOptions(
id_token: idToken,
verifierIdField: 'sub',
),
)
);
} catch (e) {
print('Login error: $e');
}
}Future<void> logout() async {
// Logout from Web3Auth
await Web3AuthFlutter.logout();
// Logout from Auth0
await auth0.webAuthentication().logout();
}import 'package:web3dart/web3dart.dart';
Future<void> getWalletInfo() async {
// Get private key from Web3Auth
final privateKey = await Web3AuthFlutter.getPrivKey();
// Create credentials
final credentials = EthPrivateKey.fromHex(privateKey);
// Get address
final address = credentials.address;
print('Wallet address: ${address.hex}');
// Get balance
final client = Web3Client('YOUR_RPC_URL', Client());
final balance = await client.getBalance(address);
print('Balance: ${balance.getValueInUnit(EtherUnit.ether)} ETH');
}- JWT Token Security: Auth0 ID tokens are short-lived and securely validated
- Non-Custodial: Private keys derived from Auth0 identity using Shamir Secret Sharing
- OAuth 2.0 / OIDC: Industry-standard authentication protocols
- Token Validation: Web3Auth validates Auth0 JWT tokens using JWKS endpoint
- Network Consistency: Never change Client ID or verifier configuration in production
- Same User Identity: Same Auth0 user always gets the same wallet address
- Enterprise Security: Auth0 provides MFA, anomaly detection, breached password detection
Problem: Auth0 login fails or doesn't redirect back
Solutions:
- Verify callback URLs are correctly configured in Auth0 dashboard
- Check that URL schemes match in both Auth0 and your app
- For iOS: Verify URL scheme in
Info.plist - For Android: Verify intent filter in
AndroidManifest.xml
Problem: "Invalid state" error
Solutions:
- This usually means callback URL mismatch
- Verify the redirect URL format exactly matches Auth0 configuration
- Check for typos in domain or bundle ID
Problem: JWT login fails with "Invalid token" error
Solutions:
- Verify Custom Verifier configuration in Web3Auth dashboard
- Check that Auth0 domain and client ID match exactly
- Ensure JWKS endpoint is accessible
- Verify
verifierIdFieldis set tosub - Check that ID token is valid and not expired
Problem: Different wallet address on each login
Solutions:
- Ensure you're using the same verifier name each time
- Verify
verifierIdFieldis consistent (sub) - Check that Client ID hasn't changed
- Ensure network (devnet/mainnet) is consistent
iOS:
- Add URL schemes to
Info.plistfor both Auth0 and Web3Auth - Allowlist
{bundleId}://authin Web3Auth dashboard - Configure Auth0 callback:
{bundleId}://YOUR_DOMAIN/ios/{bundleId}/callback
Android:
- Configure intent filters in
AndroidManifest.xmlfor both Auth0 and Web3Auth - Verify
compileSdkVersion 34 - Check package name allowlist in Web3Auth dashboard
- MetaMask Embedded Wallets Docs
- Flutter SDK Reference
- Custom Authentication Guide
- Auth0 Flutter SDK
- Auth0 Documentation
Need help? Reach out through:
This example is available under the MIT License. See the LICENSE file for more info.