Skip to content

Instantly share code, notes, and snippets.

@quetool
Last active November 28, 2023 17:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quetool/b9791ab2f1769fc03e95aa4443e58a68 to your computer and use it in GitHub Desktop.
Save quetool/b9791ab2f1769fc03e95aa4443e58a68 to your computer and use it in GitHub Desktop.
Orb example
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:web3modal_flutter/web3modal_flutter.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 {
W3MService? _w3mService;
@override
void initState() {
super.initState();
_initializeW3MService();
}
void _initializeW3MService() async {
_w3mService = W3MService(
projectId: '*************',
logLevel: LogLevel.error,
metadata: const PairingMetadata(
name: 'Orb Example',
description: 'Orb Example',
url: 'https://www.orb.ac',
icons: [
'https://play-lh.googleusercontent.com/F7vuFJeNqT-NyNAHextoMwj4zs_oiQ4MozcjuR-IZQJZuMM-Q4SSBfcoAQa_O0Kk7BM=w600-h300-pc0xffffff-pd'
],
redirect: Redirect(
native: 'flutterdapp://',
universal: 'https://www.orb.ac',
),
),
);
_w3mService?.addListener(_onServiceUpdate);
_w3mService?.web3App?.onSessionConnect.subscribe(_onSessionConnect);
await _w3mService?.init();
}
@override
void dispose() {
_w3mService?.removeListener(_onServiceUpdate);
_w3mService?.web3App?.onSessionConnect.unsubscribe(_onSessionConnect);
super.dispose();
}
void _onSessionConnect(SessionConnect? event) async {
debugPrint('[$runtimeType] _onSessionConnect $event');
await _switchToPolygonIfNeeded();
}
Future<void> _switchToPolygonIfNeeded() async {
final approvedChains = _w3mService?.getApprovedChains() ?? [];
final polygonChain = W3MChainPresets.chains['137']!;
if (!approvedChains.contains(polygonChain.namespace)) {
if (_w3mService?.selectedChain?.namespace == polygonChain.namespace) {
final firstChainId = approvedChains.first.split(':')[1];
final firstChain = W3MChainPresets.chains[firstChainId]!;
await _w3mService?.selectChain(firstChain);
}
Future.delayed(const Duration(milliseconds: 500), () async {
await _w3mService?.selectChain(polygonChain, switchChain: true);
});
}
}
void _onServiceUpdate() {
debugPrint('[$runtimeType] isConnected: ${_w3mService?.isConnected}');
debugPrint('[$runtimeType] address: ${_w3mService?.address}');
debugPrint(
'[$runtimeType] current chain: ${_w3mService?.selectedChain?.namespace}');
debugPrint(
'[$runtimeType] approved chains ${_w3mService?.getApprovedChains()}');
setState(() {
result =
'Approved methods:\n${_w3mService?.session?.namespaces['eip155']?.methods.join(', ')}';
});
}
Future<dynamic> signMessage({
required String message,
required String method,
}) async {
final web3App = _w3mService!.web3App;
final address = _w3mService!.address?.toLowerCase() ?? '';
final messageToUse = message;
final methodToUse = method;
final topic = _w3mService!.session!.topic;
_w3mService?.launchConnectedWallet();
web3App?.request(
topic: topic,
chainId: 'eip155:137',
request: SessionRequestParams(
method: methodToUse,
params: [address, messageToUse],
),
);
return null;
}
String result = '';
void _signMessage() async {
final chainId = _w3mService!.selectedChain?.chainId ?? '1';
signMessage(
message: typedDataV4(int.parse(chainId)),
method: 'eth_signTypedData_v4',
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Orb Demo',
home: Builder(
builder: (context) {
if (_w3mService == null) {
return const CircularProgressIndicator.adaptive();
}
return Scaffold(
appBar: AppBar(
title: const Text('Orb Demo'),
),
body: Container(
constraints: const BoxConstraints.expand(),
padding: const EdgeInsets.all(12.0),
child: Column(
children: !_w3mService!.isConnected
? [
W3MNetworkSelectButton(service: _w3mService!),
W3MConnectWalletButton(service: _w3mService!),
]
: [
W3MConnectWalletButton(service: _w3mService!),
const SizedBox.square(dimension: 8.0),
ElevatedButton(
onPressed: _signMessage,
child: const Text('Sign message'),
),
const SizedBox.square(dimension: 8.0),
if (result.isNotEmpty)
Text(
result,
style: const TextStyle(color: Colors.grey),
),
],
),
),
);
},
),
);
}
}
String typedDataV4(int chainId) => jsonEncode({
"types": {
"EIP712Domain": [
{"name": "name", "type": "string"},
{"name": "version", "type": "string"},
{"name": "chainId", "type": "uint256"},
{"name": "verifyingContract", "type": "address"}
],
"Person": [
{"name": "name", "type": "string"},
{"name": "wallet", "type": "address"}
],
"Mail": [
{"name": "from", "type": "Person"},
{"name": "to", "type": "Person"},
{"name": "contents", "type": "string"}
]
},
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": chainId,
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment