web3_webview 1.0.12
web3_webview: ^1.0.12 copied to clipboard
web3_webview is a powerful bridge between a DApp running inside a WebView and your Flutter application, enabling secure and seamless two-way communication between them
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:web3_webview/web3_webview.dart';
/// Example app for `web3_webview` – 3 modes: read-only, privateKey, external signer.
///
/// Loads `privateKey` from secure storage in production – here placeholders.
/// Do NOT hardcode keys in real apps.
void main() => runApp(const ExampleApp());
/// Root widget with tab demo for 3 modes + dark preview.
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
ThemeMode _mode = ThemeMode.light;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'web3_webview example',
theme: ThemeData(useMaterial3: true, brightness: Brightness.light, colorSchemeSeed: const Color(0xFF6366F1)),
darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark, colorSchemeSeed: const Color(0xFF818CF8)),
themeMode: _mode,
home: ExampleHome(
isDark: _mode == ThemeMode.dark,
onToggleDark: () => setState(() => _mode = _mode == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark),
),
);
}
}
class ExampleHome extends StatefulWidget {
final bool isDark;
final VoidCallback onToggleDark;
const ExampleHome({super.key, required this.isDark, required this.onToggleDark});
@override
State<ExampleHome> createState() => _ExampleHomeState();
}
class _ExampleHomeState extends State<ExampleHome> {
int _index = 0;
static final NetworkConfig _eth = NetworkConfig(
chainId: '0x1',
chainName: 'Ethereum Mainnet',
nativeCurrency: NativeCurrency(name: 'Ether', symbol: 'ETH', decimals: 18),
rpcUrls: ['https://mainnet.infura.io/v3/YOUR_KEY'],
blockExplorerUrls: ['https://etherscan.io'],
);
// Premium themes – auto dark via system, plus custom dark override
WalletDialogTheme get _lightTheme => WalletDialogTheme(primaryColor: const Color(0xFF6366F1));
WalletDialogTheme get _darkTheme => WalletDialogTheme.dark(primaryColor: const Color(0xFF818CF8));
// Demo private key – NEVER hardcode in production, load from secure storage
static const _demoPk =
'0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('web3_webview 1.0.11 • premium + dark'),
actions: [
IconButton(
tooltip: widget.isDark ? 'Light mode' : 'Dark mode',
icon: Icon(widget.isDark ? Icons.light_mode_rounded : Icons.dark_mode_rounded),
onPressed: widget.onToggleDark,
),
],
),
body: IndexedStack(
index: _index,
children: [
// 1. Read-only – no privateKey/signer, DApp still loads (auto dark)
Web3WebView(
web3WalletConfig: Web3WalletConfig(
currentNetwork: _eth,
supportNetworks: [_eth],
name: 'Read-only Demo',
id: 'com.example.readonly',
dialogTheme: _lightTheme,
darkDialogTheme: _darkTheme,
onError: (m, p, msg) => debugPrint('read-only onError $m: $msg'),
),
initialUrlRequest:
URLRequest(url: WebUri('https://metamask.github.io/test-dapp/')),
onPermissionRequest: (c, r) async => PermissionResponse(
resources: r.resources,
action: PermissionResponseAction.DENY,
),
),
// 2. Local private key – same themes, premium cards adapt to dark
Web3WebView(
web3WalletConfig: Web3WalletConfig(
privateKey: _demoPk,
currentNetwork: _eth,
supportNetworks: [_eth],
name: 'PrivateKey Demo',
id: 'com.example.privatekey',
dialogTheme: _lightTheme,
darkDialogTheme: _darkTheme,
onError: (m, p, msg) => debugPrint('pk onError $m: $msg'),
),
initialUrlRequest:
URLRequest(url: WebUri('https://metamask.github.io/test-dapp/')),
onPermissionRequest: (c, r) async => PermissionResponse(
resources: r.resources,
action: PermissionResponseAction.DENY,
),
),
// 3. External signer (WalletConnect etc.) – dark auto
Web3WebView(
web3WalletConfig: Web3WalletConfig(
signer: DemoSigner('0x1111111111111111111111111111111111111111'),
currentNetwork: _eth,
supportNetworks: [_eth],
name: 'External Signer Demo',
id: 'com.example.signer',
dialogTheme: _lightTheme,
darkDialogTheme: _darkTheme,
),
initialUrlRequest:
URLRequest(url: WebUri('https://metamask.github.io/test-dapp/')),
onPermissionRequest: (c, r) async => PermissionResponse(
resources: r.resources,
action: PermissionResponseAction.DENY,
),
),
],
),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
destinations: const [
NavigationDestination(icon: Icon(Icons.visibility), label: 'Read-only'),
NavigationDestination(icon: Icon(Icons.key), label: 'PrivateKey'),
NavigationDestination(icon: Icon(Icons.wallet), label: 'Signer'),
],
),
);
}
}
/// Minimal external signer demo – replace with WalletConnect / enclave logic.
class DemoSigner extends Web3Signer {
@override
final String address;
DemoSigner(this.address);
@override
Future<String> signMessage(String method, String from, dynamic message, String password) async {
// TODO: delegate to WalletConnect, show your own UI, then return 0x signature
throw WalletException('DemoSigner: implement signMessage', code: 4200);
}
@override
Future<String> sendTransaction(Map<String, dynamic> txParams) async {
// TODO: delegate to WalletConnect
throw WalletException('DemoSigner: implement sendTransaction', code: 4200);
}
}