Last active
March 24, 2024 12:16
-
-
Save quetool/f934b449ed0027f8b435622a2719328a to your computer and use it in GitHub Desktop.
Connect to a Wallet using walletconnect_flutter_v2 and Authenticate with it (if supported)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:convert'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter/services.dart'; | |
import 'package:url_launcher/url_launcher_string.dart'; | |
import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatefulWidget { | |
const MyApp({super.key}); | |
@override | |
State<MyApp> createState() => _MyAppState(); | |
} | |
class _MyAppState extends State<MyApp> with WidgetsBindingObserver { | |
Web3App? _web3app; | |
SessionData? _sessionData; | |
String _logs = ''; | |
@override | |
void initState() { | |
super.initState(); | |
_initWalletConnect(); | |
} | |
Future<void> _initWalletConnect() async { | |
_web3app = await Web3App.createInstance( | |
projectId: '***************', | |
metadata: const PairingMetadata( | |
name: 'Flutter WalletConnect', | |
description: 'Flutter WalletConnect Dapp Example', | |
url: 'https://walletconnect.com/', | |
icons: [ | |
'https://walletconnect.com/walletconnect-logo.png', | |
], | |
), | |
); | |
} | |
Future<void> connectWallet(String deepLink) async { | |
if (_web3app == null) { | |
await _initWalletConnect(); | |
} | |
final connectResponse = await _web3app!.connect( | |
optionalNamespaces: { | |
'eip155': const RequiredNamespace( | |
chains: ['eip155:1'], | |
// Not every method may be needed for your purposes | |
methods: [ | |
"personal_sign", | |
"eth_sendTransaction", | |
// "eth_accounts", | |
// "eth_requestAccounts", | |
// "eth_sendRawTransaction", | |
// "eth_sign", | |
// "eth_signTransaction", | |
// "eth_signTypedData", | |
// "eth_signTypedData_v3", | |
// "eth_signTypedData_v4", | |
// "wallet_switchEthereumChain", | |
// "wallet_addEthereumChain", | |
// "wallet_getPermissions", | |
// "wallet_requestPermissions", | |
// "wallet_registerOnboarding", | |
// "wallet_watchAsset", | |
// "wallet_scanQRCode", | |
], | |
// Not every event may be needed for your purposes | |
events: [ | |
"chainChanged", | |
"accountsChanged", | |
// "message", | |
// "disconnect", | |
// "connect", | |
], | |
), | |
}, | |
); | |
setState(() => _logs += '$connectResponse\n\n'); | |
final uri = connectResponse.uri; | |
if (uri == null) { | |
throw Exception('Uri not found'); | |
} | |
final url = '${deepLink}wc?uri=${Uri.encodeComponent('$uri')}'; | |
await launchUrlString(url, mode: LaunchMode.externalApplication); | |
_sessionData = await connectResponse.session.future; | |
setState(() { | |
_logs += 'sessionData ${jsonEncode(_sessionData?.toJson())}\n\n'; | |
}); | |
} | |
Future<void> requestAuthWithWallet(String deepLink) async { | |
if (_web3app == null) { | |
await _initWalletConnect(); | |
await connectWallet(deepLink); | |
} | |
// Send off an auth request now that the pairing/session is established | |
// Not every wallet my be supporting Auth SDK | |
setState(() => _logs += 'Requesting authentication...\n\n'); | |
final authResponse = await _web3app!.requestAuth( | |
pairingTopic: _sessionData!.pairingTopic, | |
params: AuthRequestParams( | |
chainId: 'eip155:1', | |
domain: 'walletconnect.org', | |
aud: 'https://walletconnect.org/login', | |
), | |
); | |
final authCompletion = await authResponse.completer.future; | |
setState(() => _logs += '$authCompletion\n\n'); | |
if (authCompletion.error != null) { | |
throw authCompletion.error!; | |
} | |
} | |
final _messangerKey = GlobalKey<ScaffoldMessengerState>(); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Connect to Wallet demo', | |
home: ScaffoldMessenger( | |
key: _messangerKey, | |
child: Scaffold( | |
appBar: AppBar( | |
title: const Text('Connect to Wallet demo'), | |
), | |
body: SizedBox( | |
width: MediaQuery.of(context).size.width, | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
crossAxisAlignment: CrossAxisAlignment.center, | |
mainAxisSize: MainAxisSize.max, | |
children: [ | |
Padding( | |
padding: const EdgeInsets.only( | |
left: 8.0, | |
top: 8.0, | |
right: 8.0, | |
), | |
child: Wrap( | |
spacing: 12.0, | |
runSpacing: 12.0, | |
children: [ | |
ElevatedButton( | |
child: const Text('MetaMask'), | |
onPressed: () => _connectWithWallet('metamask://'), | |
), | |
ElevatedButton( | |
child: const Text('Rainbow'), | |
onPressed: () => _connectWithWallet('rainbow://'), | |
), | |
ElevatedButton( | |
child: const Text('Trust'), | |
onPressed: () => _connectWithWallet('trust://'), | |
), | |
], | |
), | |
), | |
Expanded( | |
child: SingleChildScrollView( | |
child: Padding( | |
padding: const EdgeInsets.all(8.0), | |
child: GestureDetector( | |
child: Text(_logs), | |
onLongPress: () { | |
Clipboard.setData(ClipboardData(text: _logs)).then( | |
(value) => _messangerKey.currentState?.showSnackBar( | |
const SnackBar( | |
content: Text('Logs copied to Clipboard'), | |
), | |
), | |
); | |
}, | |
), | |
), | |
), | |
), | |
], | |
), | |
), | |
), | |
), | |
); | |
} | |
void _connectWithWallet(String deepLink) { | |
connectWallet(deepLink).then((_) { | |
setState(() => _logs += '✅ connected\n\n'); | |
requestAuthWithWallet(deepLink).then((_) { | |
setState(() => _logs += '✅ authenticated\n\n'); | |
}).catchError((error) { | |
setState(() => _logs += '❌ auth error $error\n\n'); | |
}); | |
}).catchError((error) { | |
setState(() => _logs += '❌ connection error $error\n\n'); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
demo.mov