From 1712b247da1e7e8c9433cd199a100171991ef8e0 Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Thu, 25 Jan 2024 16:33:37 +0100 Subject: [PATCH 1/6] minor changes --- example/lib/home_page.dart | 23 +++++++++- example/lib/widgets/session_widget.dart | 46 +++++++++++++------ example/pubspec.lock | 12 ++--- .../models/wc_sample_wallets.dart | 18 ++++---- lib/services/w3m_service/w3m_service.dart | 13 ++++-- pubspec.lock | 12 ++--- pubspec.yaml | 2 +- 7 files changed, 85 insertions(+), 41 deletions(-) diff --git a/example/lib/home_page.dart b/example/lib/home_page.dart index 33a8d06e..2082dffc 100644 --- a/example/lib/home_page.dart +++ b/example/lib/home_page.dart @@ -30,7 +30,14 @@ class _MyHomePageState extends State { void _initializeService() async { // See https://docs.walletconnect.com/web3modal/flutter/custom-chains - W3MChainPresets.chains.putIfAbsent('42220', () => _exampleCustomChain); + W3MChainPresets.chains.putIfAbsent( + _exampleCustomChain.chainId, + () => _exampleCustomChain, + ); + // W3MChainPresets.chains.putIfAbsent( + // _arbitrumSepolia.chainId, + // () => _arbitrumSepolia, + // ); _w3mService = W3MService( projectId: DartDefines.projectId, @@ -40,7 +47,7 @@ class _MyHomePageState extends State { description: StringConstants.w3mPageTitleV3, url: 'https://web3modal.com/', icons: [ - 'https://raw.githubusercontent.com/WalletConnect/Web3ModalFlutter/master/assets/AppIcon.png' + 'https://docs.walletconnect.com/assets/images/web3modalLogo-2cee77e07851ba0a710b56d03d4d09dd.png' ], redirect: Redirect( native: 'web3modalflutter://', @@ -207,3 +214,15 @@ final _exampleCustomChain = W3MChainInfo( url: 'https://explorer.celo.org/mainnet', ), ); + +// final _arbitrumSepolia = W3MChainInfo( +// chainName: 'Arbitrum Sepolia Testnet', +// chainId: '421614', +// namespace: 'eip155:421614', +// tokenName: 'ETH', +// rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc', +// blockExplorer: W3MBlockExplorer( +// name: 'Arbitrum Sepolia Testnet', +// url: 'https://sepolia.arbiscan.io/', +// ), +// ); diff --git a/example/lib/widgets/session_widget.dart b/example/lib/widgets/session_widget.dart index 084be067..e1eb669b 100644 --- a/example/lib/widgets/session_widget.dart +++ b/example/lib/widgets/session_widget.dart @@ -27,32 +27,50 @@ class SessionWidgetState extends State { @override Widget build(BuildContext context) { final session = widget.w3mService.session!; - final iconImage = session.sessionData?.peer.metadata.icons.first ?? ''; + String iconImage = ''; + if ((session.sessionData?.peer.metadata.icons ?? []).isNotEmpty) { + iconImage = session.sessionData?.peer.metadata.icons.first ?? ''; + } final List children = [ const SizedBox(height: StyleConstants.linear16), - // WALLET NAME LABEL Row( children: [ if (iconImage.isNotEmpty) - CircleAvatar( - radius: 50.0, - backgroundImage: NetworkImage(iconImage), + Row( + children: [ + CircleAvatar( + radius: 30.0, + backgroundImage: NetworkImage(iconImage), + ), + const SizedBox(width: 10.0), + ], ), Expanded( - child: Text( - session.connectedWalletName ?? '', - style: Web3ModalTheme.getDataOf(context) - .textStyles - .large600 - .copyWith( - color: Web3ModalTheme.colorsOf(context).foreground100, + child: Row( + children: [ + Expanded( + child: Text( + session.connectedWalletName ?? '', + style: Web3ModalTheme.getDataOf(context) + .textStyles + .large600 + .copyWith( + color: Web3ModalTheme.colorsOf(context).foreground100, + ), ), - textAlign: TextAlign.center, + ), + IconButton( + onPressed: () { + widget.w3mService.launchConnectedWallet(); + }, + icon: const Icon(Icons.open_in_new), + ) + ], ), ), ], ), - const SizedBox(height: StyleConstants.linear8), + const SizedBox(height: StyleConstants.linear16), // TOPIC LABEL Visibility( visible: session.topic != null, diff --git a/example/pubspec.lock b/example/pubspec.lock index 99b10171..a84851dc 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -428,10 +428,10 @@ packages: dependency: transitive description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -676,10 +676,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1065,10 +1065,10 @@ packages: dependency: transitive description: name: walletconnect_flutter_v2 - sha256: e26ca98cfd6b8d5dc9c5f7e581999ab314d5134c0ffcddb73ef750f13b322d9c + sha256: "419f58dbb5b636f2907b1e74a27e5a4da08c5c320e40fee21b69b65f852769ce" url: "https://pub.dev" source: hosted - version: "2.1.13" + version: "2.1.14" watcher: dependency: transitive description: diff --git a/lib/services/explorer_service/models/wc_sample_wallets.dart b/lib/services/explorer_service/models/wc_sample_wallets.dart index c5b3de0b..bcc10cdf 100644 --- a/lib/services/explorer_service/models/wc_sample_wallets.dart +++ b/lib/services/explorer_service/models/wc_sample_wallets.dart @@ -29,15 +29,14 @@ class WCSampleWallets { 'ios': W3MWalletInfo( listing: Listing.fromJson({ 'id': '123456789012345678901234567890', - 'name': 'WC Wallet', + 'name': 'Wallet (Swift)', 'homepage': 'https://walletconnect.com', - 'image_id': - 'https://images.prismic.io/wallet-connect/65785a56531ac2845a260732_WalletConnect-App-Logo-1024X1024.png', + 'image_id': _walletImage, 'order': 30, 'mobile_link': 'walletapp://', 'app_store': 'https://apps.apple.com/app/apple-store/', 'play_store': - 'https://play.google.com/store/apps/details?id=com.walletconnect.sample.wallet', + '$_playstoreUrl${nativeData["123456789012345678901234567890"]?["android"]?.schema}', }), installed: false, recent: false, @@ -45,18 +44,21 @@ class WCSampleWallets { 'flutter': W3MWalletInfo( listing: Listing.fromJson({ 'id': '123456789012345678901234567891', - 'name': 'WC Flutter Wallet', + 'name': 'Wallet (Flutter)', 'homepage': 'https://walletconnect.com', - 'image_id': - 'https://images.prismic.io/wallet-connect/65785a56531ac2845a260732_WalletConnect-App-Logo-1024X1024.png', + 'image_id': _walletImage, 'order': 30, 'mobile_link': 'wcflutterwallet://', 'app_store': 'https://apps.apple.com/app/apple-store/', 'play_store': - 'https://play.google.com/store/apps/details?id=com.walletconnect.flutterwallet', + '$_playstoreUrl${nativeData["123456789012345678901234567891"]?["android"]?.schema}', }), installed: false, recent: false, ), }; + + static const _playstoreUrl = 'https://play.google.com/store/apps/details?id='; + static const _walletImage = + 'https://docs.walletconnect.com/assets/images/web3walletLogo-54d3b546146931ceaf47a3500868a73a.png'; } diff --git a/lib/services/w3m_service/w3m_service.dart b/lib/services/w3m_service/w3m_service.dart index 39588bac..6e0c16a9 100644 --- a/lib/services/w3m_service/w3m_service.dart +++ b/lib/services/w3m_service/w3m_service.dart @@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:web3modal_flutter/constants/string_constants.dart'; +import 'package:web3modal_flutter/pages/account_page.dart'; import 'package:web3modal_flutter/services/coinbase_service/coinbase_service.dart'; import 'package:web3modal_flutter/services/coinbase_service/i_coinbase_service.dart'; import 'package:web3modal_flutter/services/coinbase_service/models/coinbase_data.dart'; @@ -348,18 +349,22 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { // Reset the explorer explorerService.instance.search(query: null); widgetStack.instance.clear(); - _context = context; final isBottomSheet = platformUtils.instance.isBottomSheet(); - final theme = Web3ModalTheme.maybeOf(_context!); + + Widget? showWidget = startWidget; + if (_isConnected) { + showWidget = const AccountPage(); + } + final childWidget = theme == null ? Web3ModalTheme( themeData: const Web3ModalThemeData(), - child: Web3Modal(startWidget: startWidget), + child: Web3Modal(startWidget: showWidget), ) - : Web3Modal(startWidget: startWidget); + : Web3Modal(startWidget: showWidget); final rootWidget = Web3ModalProvider( service: this, diff --git a/pubspec.lock b/pubspec.lock index f92adcc3..ee2b28a5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -404,10 +404,10 @@ packages: dependency: "direct main" description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -660,10 +660,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1049,10 +1049,10 @@ packages: dependency: "direct main" description: name: walletconnect_flutter_v2 - sha256: e26ca98cfd6b8d5dc9c5f7e581999ab314d5134c0ffcddb73ef750f13b322d9c + sha256: "419f58dbb5b636f2907b1e74a27e5a4da08c5c320e40fee21b69b65f852769ce" url: "https://pub.dev" source: hosted - version: "2.1.13" + version: "2.1.14" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d6b51b1d..010ffe40 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: qr_flutter_wc: ^0.0.3 shimmer: ^3.0.0 url_launcher: ^6.2.3 - walletconnect_flutter_v2: ^2.1.13 + walletconnect_flutter_v2: ^2.1.14 dev_dependencies: build_runner: ^2.4.7 From a481b6d401a751210717deddee0b44ec41cbb293 Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Mon, 29 Jan 2024 12:56:53 +0100 Subject: [PATCH 2/6] minor changes --- example/lib/home_page.dart | 34 +++---- example/lib/widgets/auth_item.dart | 38 ++++---- example/lib/widgets/chain_button.dart | 94 +++++++++---------- example/lib/widgets/event_widget.dart | 64 ++++++------- example/lib/widgets/pairing_item.dart | 38 ++++---- example/lib/widgets/session_item.dart | 38 ++++---- .../ledger_service/ledger_service.dart | 18 ++-- 7 files changed, 162 insertions(+), 162 deletions(-) diff --git a/example/lib/home_page.dart b/example/lib/home_page.dart index 2082dffc..4fc78a8d 100644 --- a/example/lib/home_page.dart +++ b/example/lib/home_page.dart @@ -30,14 +30,8 @@ class _MyHomePageState extends State { void _initializeService() async { // See https://docs.walletconnect.com/web3modal/flutter/custom-chains - W3MChainPresets.chains.putIfAbsent( - _exampleCustomChain.chainId, - () => _exampleCustomChain, - ); - // W3MChainPresets.chains.putIfAbsent( - // _arbitrumSepolia.chainId, - // () => _arbitrumSepolia, - // ); + W3MChainPresets.chains.putIfAbsent(_celo.chainId, () => _celo); + W3MChainPresets.chains.putIfAbsent(_sepolia.chainId, () => _sepolia); _w3mService = W3MService( projectId: DartDefines.projectId, @@ -203,7 +197,7 @@ class _ConnectedView extends StatelessWidget { } } -final _exampleCustomChain = W3MChainInfo( +final _celo = W3MChainInfo( chainName: 'Celo', namespace: 'eip155:42220', chainId: '42220', @@ -215,14 +209,14 @@ final _exampleCustomChain = W3MChainInfo( ), ); -// final _arbitrumSepolia = W3MChainInfo( -// chainName: 'Arbitrum Sepolia Testnet', -// chainId: '421614', -// namespace: 'eip155:421614', -// tokenName: 'ETH', -// rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc', -// blockExplorer: W3MBlockExplorer( -// name: 'Arbitrum Sepolia Testnet', -// url: 'https://sepolia.arbiscan.io/', -// ), -// ); +final _sepolia = W3MChainInfo( + chainName: 'Sepolia Testnet', + chainId: '11155111', + namespace: 'eip155:11155111', + tokenName: 'ETH', + rpcUrl: 'https://rpc.sepolia.org', + blockExplorer: W3MBlockExplorer( + name: 'Arbitrum Sepolia Testnet', + url: 'https://sepolia.etherscan.io/', + ), +); diff --git a/example/lib/widgets/auth_item.dart b/example/lib/widgets/auth_item.dart index 9fbc3c24..39cc3d3d 100644 --- a/example/lib/widgets/auth_item.dart +++ b/example/lib/widgets/auth_item.dart @@ -1,22 +1,22 @@ -import 'package:flutter/material.dart'; -import 'package:web3modal_flutter/web3modal_flutter.dart'; +// import 'package:flutter/material.dart'; +// import 'package:web3modal_flutter/web3modal_flutter.dart'; -class AuthItem extends StatelessWidget { - const AuthItem({ - required Key key, - required this.auth, - required this.onTap, - }) : super(key: key); +// class AuthItem extends StatelessWidget { +// const AuthItem({ +// required Key key, +// required this.auth, +// required this.onTap, +// }) : super(key: key); - final StoredCacao auth; - final void Function() onTap; +// final StoredCacao auth; +// final void Function() onTap; - @override - Widget build(BuildContext context) { - return ListTile( - title: Text(auth.p.domain), - subtitle: Text(auth.p.iss), - onTap: onTap, - ); - } -} +// @override +// Widget build(BuildContext context) { +// return ListTile( +// title: Text(auth.p.domain), +// subtitle: Text(auth.p.iss), +// onTap: onTap, +// ); +// } +// } diff --git a/example/lib/widgets/chain_button.dart b/example/lib/widgets/chain_button.dart index 59ab21ad..ba03262a 100644 --- a/example/lib/widgets/chain_button.dart +++ b/example/lib/widgets/chain_button.dart @@ -1,50 +1,50 @@ -import 'package:flutter/material.dart'; -import 'package:walletconnect_flutter_dapp/models/chain_metadata.dart'; -import 'package:walletconnect_flutter_dapp/utils/constants.dart'; +// import 'package:flutter/material.dart'; +// import 'package:walletconnect_flutter_dapp/models/chain_metadata.dart'; +// import 'package:walletconnect_flutter_dapp/utils/constants.dart'; -class ChainButton extends StatelessWidget { - const ChainButton({ - super.key, - required this.chain, - required this.onPressed, - this.selected = false, - }); +// class ChainButton extends StatelessWidget { +// const ChainButton({ +// super.key, +// required this.chain, +// required this.onPressed, +// this.selected = false, +// }); - final ChainMetadata chain; - final VoidCallback onPressed; - final bool selected; +// final ChainMetadata chain; +// final VoidCallback onPressed; +// final bool selected; - @override - Widget build(BuildContext context) { - return Container( - width: double.infinity, - height: StyleConstants.linear48, - margin: const EdgeInsets.symmetric( - vertical: StyleConstants.linear8, - ), - child: ElevatedButton( - onPressed: onPressed, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Colors.white, - ), - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - side: BorderSide( - color: chain.color, - width: selected ? 6 : 2, - ), - borderRadius: BorderRadius.circular( - StyleConstants.linear8, - ), - ), - ), - ), - child: Text( - chain.w3mChainInfo.chainName, - style: StyleConstants.buttonText, - ), - ), - ); - } -} +// @override +// Widget build(BuildContext context) { +// return Container( +// width: double.infinity, +// height: StyleConstants.linear48, +// margin: const EdgeInsets.symmetric( +// vertical: StyleConstants.linear8, +// ), +// child: ElevatedButton( +// onPressed: onPressed, +// style: ButtonStyle( +// backgroundColor: MaterialStateProperty.all( +// Colors.white, +// ), +// shape: MaterialStateProperty.all( +// RoundedRectangleBorder( +// side: BorderSide( +// color: chain.color, +// width: selected ? 6 : 2, +// ), +// borderRadius: BorderRadius.circular( +// StyleConstants.linear8, +// ), +// ), +// ), +// ), +// child: Text( +// chain.w3mChainInfo.chainName, +// style: StyleConstants.buttonText, +// ), +// ), +// ); +// } +// } diff --git a/example/lib/widgets/event_widget.dart b/example/lib/widgets/event_widget.dart index b81ee3fd..4b7d312b 100644 --- a/example/lib/widgets/event_widget.dart +++ b/example/lib/widgets/event_widget.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:walletconnect_flutter_dapp/utils/constants.dart'; -import 'package:walletconnect_flutter_dapp/utils/string_constants.dart'; +// import 'package:flutter/material.dart'; +// import 'package:walletconnect_flutter_dapp/utils/constants.dart'; +// import 'package:walletconnect_flutter_dapp/utils/string_constants.dart'; -class EventWidget extends StatelessWidget { - const EventWidget({ - super.key, - required this.title, - required this.content, - }); +// class EventWidget extends StatelessWidget { +// const EventWidget({ +// super.key, +// required this.title, +// required this.content, +// }); - final String title; - final String content; +// final String title; +// final String content; - @override - Widget build(BuildContext context) { - return AlertDialog( - title: Text( - title, - style: StyleConstants.titleText, - ), - content: Text(content), - actions: [ - TextButton( - child: const Text( - StringConstants.ok, - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - } -} +// @override +// Widget build(BuildContext context) { +// return AlertDialog( +// title: Text( +// title, +// style: StyleConstants.titleText, +// ), +// content: Text(content), +// actions: [ +// TextButton( +// child: const Text( +// StringConstants.ok, +// ), +// onPressed: () { +// Navigator.of(context).pop(); +// }, +// ), +// ], +// ); +// } +// } diff --git a/example/lib/widgets/pairing_item.dart b/example/lib/widgets/pairing_item.dart index 6e803ad8..9354e584 100644 --- a/example/lib/widgets/pairing_item.dart +++ b/example/lib/widgets/pairing_item.dart @@ -1,22 +1,22 @@ -import 'package:flutter/material.dart'; -import 'package:web3modal_flutter/web3modal_flutter.dart'; +// import 'package:flutter/material.dart'; +// import 'package:web3modal_flutter/web3modal_flutter.dart'; -class PairingItem extends StatelessWidget { - const PairingItem({ - required Key key, - required this.pairing, - required this.onTap, - }) : super(key: key); +// class PairingItem extends StatelessWidget { +// const PairingItem({ +// required Key key, +// required this.pairing, +// required this.onTap, +// }) : super(key: key); - final PairingInfo pairing; - final void Function() onTap; +// final PairingInfo pairing; +// final void Function() onTap; - @override - Widget build(BuildContext context) { - return ListTile( - title: Text(pairing.peerMetadata?.name ?? 'Unknown'), - subtitle: Text(pairing.peerMetadata?.url ?? 'Unknown'), - onTap: onTap, - ); - } -} +// @override +// Widget build(BuildContext context) { +// return ListTile( +// title: Text(pairing.peerMetadata?.name ?? 'Unknown'), +// subtitle: Text(pairing.peerMetadata?.url ?? 'Unknown'), +// onTap: onTap, +// ); +// } +// } diff --git a/example/lib/widgets/session_item.dart b/example/lib/widgets/session_item.dart index 903aade8..53d0c469 100644 --- a/example/lib/widgets/session_item.dart +++ b/example/lib/widgets/session_item.dart @@ -1,22 +1,22 @@ -import 'package:flutter/material.dart'; -import 'package:web3modal_flutter/web3modal_flutter.dart'; +// import 'package:flutter/material.dart'; +// import 'package:web3modal_flutter/web3modal_flutter.dart'; -class SessionItem extends StatelessWidget { - const SessionItem({ - required Key key, - required this.session, - required this.onTap, - }) : super(key: key); +// class SessionItem extends StatelessWidget { +// const SessionItem({ +// required Key key, +// required this.session, +// required this.onTap, +// }) : super(key: key); - final SessionData session; - final void Function() onTap; +// final SessionData session; +// final void Function() onTap; - @override - Widget build(BuildContext context) { - return ListTile( - title: Text(session.peer.metadata.name), - subtitle: Text(session.peer.metadata.url), - onTap: onTap, - ); - } -} +// @override +// Widget build(BuildContext context) { +// return ListTile( +// title: Text(session.peer.metadata.name), +// subtitle: Text(session.peer.metadata.url), +// onTap: onTap, +// ); +// } +// } diff --git a/lib/services/ledger_service/ledger_service.dart b/lib/services/ledger_service/ledger_service.dart index 0f0551f2..197c638b 100644 --- a/lib/services/ledger_service/ledger_service.dart +++ b/lib/services/ledger_service/ledger_service.dart @@ -5,12 +5,18 @@ import 'package:web3modal_flutter/web3modal_flutter.dart'; class LedgerService extends ILedgerService { @override Future getBalance(String rpcUrl, String address) async { - final client = Web3Client(rpcUrl, Client()); - final EtherAmount amount = await client.getBalance( - EthereumAddress.fromHex(address), - ); - - return amount.getValueInUnit(EtherUnit.ether); + try { + final client = Web3Client(rpcUrl, Client()); + final amount = await client.getBalance(EthereumAddress.fromHex(address)); + return amount.getValueInUnit(EtherUnit.ether); + } catch (e, s) { + W3MLoggerUtil.logger.e( + '[$runtimeType] getBalance error', + error: e, + stackTrace: s, + ); + return 0.0; + } } @override From 1106a2533e3050ffbd63474ea47fce6cb54f63f7 Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Thu, 1 Feb 2024 18:14:36 +0100 Subject: [PATCH 3/6] implementation of WCFV2 2.2.0-beta01 --- example/lib/home_page.dart | 2 +- .../lib/utils/crypto/chain_data_wrapper.dart | 5 + example/lib/utils/crypto/contract.dart | 484 ++++++------------ example/lib/utils/crypto/eip155.dart | 125 +++-- .../lib/utils/crypto/web3dart_extension.dart | 17 - example/lib/widgets/session_widget.dart | 105 ++-- example/pubspec.lock | 12 +- example/pubspec.yaml | 1 + lib/services/w3m_service/i_w3m_service.dart | 18 + lib/services/w3m_service/w3m_service.dart | 46 ++ pubspec.lock | 4 +- pubspec.yaml | 3 +- test/mock_classes.mocks.dart | 96 ++++ 13 files changed, 493 insertions(+), 425 deletions(-) delete mode 100644 example/lib/utils/crypto/web3dart_extension.dart diff --git a/example/lib/home_page.dart b/example/lib/home_page.dart index 4fc78a8d..89744596 100644 --- a/example/lib/home_page.dart +++ b/example/lib/home_page.dart @@ -214,7 +214,7 @@ final _sepolia = W3MChainInfo( chainId: '11155111', namespace: 'eip155:11155111', tokenName: 'ETH', - rpcUrl: 'https://rpc.sepolia.org', + rpcUrl: 'https://ethereum-sepolia.publicnode.com', blockExplorer: W3MBlockExplorer( name: 'Arbitrum Sepolia Testnet', url: 'https://sepolia.etherscan.io/', diff --git a/example/lib/utils/crypto/chain_data_wrapper.dart b/example/lib/utils/crypto/chain_data_wrapper.dart index eda2bbd2..fba28598 100644 --- a/example/lib/utils/crypto/chain_data_wrapper.dart +++ b/example/lib/utils/crypto/chain_data_wrapper.dart @@ -54,6 +54,11 @@ class ChainDataWrapper { color: Colors.purple.shade700, w3mChainInfo: W3MChainPresets.chains['1088']!, ), + ChainMetadata( + type: ChainType.eip155, + color: Colors.blue.shade200, + w3mChainInfo: W3MChainPresets.chains['11155111']!, + ), // const ChainMetadata( // type: ChainType.solana, // chainId: 'solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ', diff --git a/example/lib/utils/crypto/contract.dart b/example/lib/utils/crypto/contract.dart index 79ce062b..ca128c39 100644 --- a/example/lib/utils/crypto/contract.dart +++ b/example/lib/utils/crypto/contract.dart @@ -1,469 +1,279 @@ -class ContractDetails { - // Tether (USDT) - static const contractAddress = '0xdac17f958d2ee523a2206206994597c13d831ec7'; +class SepoliaTestContract { + // Alfreedoms2 ALF2 in Sepolia + // DEPLOY https://sepolia.etherscan.io/tx/0xebf287281abbc976b7cf6956a7f5f66338935d324c6453a350e3bb42ff7bd4e2 + // MINT https://sepolia.etherscan.io/tx/0x04a015504be7420a40a59936bfcca9302e55700fd00129059444539770fed5e7 + // CONTRACT https://sepolia.etherscan.io/address/0xBe60D05C11BD1C365849C824E0C2D880d2466eAF + // TRANSFERS https://sepolia.etherscan.io/token/0xbe60d05c11bd1c365849c824e0c2d880d2466eaf?a=0x59e2f66C0E96803206B6486cDb39029abAE834c0 + // SOURCIFY https://repo.sourcify.dev/contracts/full_match/11155111/0xBe60D05C11BD1C365849C824E0C2D880d2466eAF/ + static const contractAddress = '0xBe60D05C11BD1C365849C824E0C2D880d2466eAF'; static const readContractAbi = [ { - "constant": true, - "inputs": [], - "name": "name", - "outputs": [ - {"name": "", "type": "string"} + "inputs": [ + {"internalType": "address", "name": "initialOwner", "type": "address"} ], - "payable": false, - "stateMutability": "view", - "type": "function" + "stateMutability": "nonpayable", + "type": "constructor" }, { - "constant": false, "inputs": [ - {"name": "_upgradedAddress", "type": "address"} + {"internalType": "address", "name": "spender", "type": "address"}, + {"internalType": "uint256", "name": "allowance", "type": "uint256"}, + {"internalType": "uint256", "name": "needed", "type": "uint256"} ], - "name": "deprecate", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "ERC20InsufficientAllowance", + "type": "error" }, { - "constant": false, "inputs": [ - {"name": "_spender", "type": "address"}, - {"name": "_value", "type": "uint256"} + {"internalType": "address", "name": "sender", "type": "address"}, + {"internalType": "uint256", "name": "balance", "type": "uint256"}, + {"internalType": "uint256", "name": "needed", "type": "uint256"} ], - "name": "approve", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "ERC20InsufficientBalance", + "type": "error" }, { - "constant": true, - "inputs": [], - "name": "deprecated", - "outputs": [ - {"name": "", "type": "bool"} + "inputs": [ + {"internalType": "address", "name": "approver", "type": "address"} ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "ERC20InvalidApprover", + "type": "error" }, { - "constant": false, "inputs": [ - {"name": "_evilUser", "type": "address"} + {"internalType": "address", "name": "receiver", "type": "address"} ], - "name": "addBlackList", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "ERC20InvalidReceiver", + "type": "error" }, { - "constant": true, - "inputs": [], - "name": "totalSupply", - "outputs": [ - {"name": "", "type": "uint256"} + "inputs": [ + {"internalType": "address", "name": "sender", "type": "address"} ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "ERC20InvalidSender", + "type": "error" }, { - "constant": false, "inputs": [ - {"name": "_from", "type": "address"}, - {"name": "_to", "type": "address"}, - {"name": "_value", "type": "uint256"} + {"internalType": "address", "name": "spender", "type": "address"} ], - "name": "transferFrom", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" + "name": "ERC20InvalidSpender", + "type": "error" }, { - "constant": true, - "inputs": [], - "name": "upgradedAddress", - "outputs": [ - {"name": "", "type": "address"} + "inputs": [ + {"internalType": "address", "name": "owner", "type": "address"} ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "OwnableInvalidOwner", + "type": "error" }, { - "constant": true, "inputs": [ - {"name": "", "type": "address"} - ], - "name": "balances", - "outputs": [ - {"name": "", "type": "uint256"} + {"internalType": "address", "name": "account", "type": "address"} ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "OwnableUnauthorizedAccount", + "type": "error" }, { - "constant": true, - "inputs": [], - "name": "decimals", - "outputs": [ - {"name": "", "type": "uint256"} + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "Approval", + "type": "event" }, { - "constant": true, - "inputs": [], - "name": "maximumFee", - "outputs": [ - {"name": "", "type": "uint256"} + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } ], - "payable": false, - "stateMutability": "view", - "type": "function" + "name": "Transfer", + "type": "event" }, { - "constant": true, - "inputs": [], - "name": "_totalSupply", + "inputs": [ + {"internalType": "address", "name": "owner", "type": "address"}, + {"internalType": "address", "name": "spender", "type": "address"} + ], + "name": "allowance", "outputs": [ - {"name": "", "type": "uint256"} + {"internalType": "uint256", "name": "", "type": "uint256"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": false, - "inputs": [], - "name": "unpause", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, "inputs": [ - {"name": "_maker", "type": "address"} + {"internalType": "address", "name": "spender", "type": "address"}, + {"internalType": "uint256", "name": "value", "type": "uint256"} ], - "name": "getBlackListStatus", + "name": "approve", "outputs": [ - {"name": "", "type": "bool"} + {"internalType": "bool", "name": "", "type": "bool"} ], - "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [ - {"name": "", "type": "address"}, - {"name": "", "type": "address"} + {"internalType": "address", "name": "account", "type": "address"} ], - "name": "allowed", + "name": "balanceOf", "outputs": [ - {"name": "", "type": "uint256"} + {"internalType": "uint256", "name": "", "type": "uint256"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "paused", + "name": "decimals", "outputs": [ - {"name": "", "type": "bool"} + {"internalType": "uint8", "name": "", "type": "uint8"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ - {"name": "who", "type": "address"} + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "amount", "type": "uint256"} ], - "name": "balanceOf", - "outputs": [ - {"name": "", "type": "uint256"} - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "pause", + "name": "mint", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": true, "inputs": [], - "name": "getOwner", + "name": "name", "outputs": [ - {"name": "", "type": "address"} + {"internalType": "string", "name": "", "type": "string"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], "name": "owner", "outputs": [ - {"name": "", "type": "address"} + {"internalType": "address", "name": "", "type": "address"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "symbol", - "outputs": [ - {"name": "", "type": "string"} - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - {"name": "_to", "type": "address"}, - {"name": "_value", "type": "uint256"} - ], - "name": "transfer", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - {"name": "newBasisPoints", "type": "uint256"}, - {"name": "newMaxFee", "type": "uint256"} - ], - "name": "setParams", + "name": "renounceOwnership", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, - "inputs": [ - {"name": "amount", "type": "uint256"} - ], - "name": "issue", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - {"name": "amount", "type": "uint256"} - ], - "name": "redeem", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - {"name": "_owner", "type": "address"}, - {"name": "_spender", "type": "address"} - ], - "name": "allowance", + "inputs": [], + "name": "symbol", "outputs": [ - {"name": "remaining", "type": "uint256"} + {"internalType": "string", "name": "", "type": "string"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [], - "name": "basisPointsRate", + "name": "totalSupply", "outputs": [ - {"name": "", "type": "uint256"} + {"internalType": "uint256", "name": "", "type": "uint256"} ], - "payable": false, "stateMutability": "view", "type": "function" }, { - "constant": true, "inputs": [ - {"name": "", "type": "address"} + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "value", "type": "uint256"} ], - "name": "isBlackListed", + "name": "transfer", "outputs": [ - {"name": "", "type": "bool"} + {"internalType": "bool", "name": "", "type": "bool"} ], - "payable": false, - "stateMutability": "view", + "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ - {"name": "_clearedUser", "type": "address"} + {"internalType": "address", "name": "from", "type": "address"}, + {"internalType": "address", "name": "to", "type": "address"}, + {"internalType": "uint256", "name": "value", "type": "uint256"} ], - "name": "removeBlackList", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "MAX_UINT", + "name": "transferFrom", "outputs": [ - {"name": "", "type": "uint256"} + {"internalType": "bool", "name": "", "type": "bool"} ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - {"name": "newOwner", "type": "address"} - ], - "name": "transferOwnership", - "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" }, { - "constant": false, "inputs": [ - {"name": "_blackListedUser", "type": "address"} + {"internalType": "address", "name": "newOwner", "type": "address"} ], - "name": "destroyBlackFunds", + "name": "transferOwnership", "outputs": [], - "payable": false, "stateMutability": "nonpayable", "type": "function" - }, - { - "inputs": [ - {"name": "_initialSupply", "type": "uint256"}, - {"name": "_name", "type": "string"}, - {"name": "_symbol", "type": "string"}, - {"name": "_decimals", "type": "uint256"} - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "amount", "type": "uint256"} - ], - "name": "Issue", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "amount", "type": "uint256"} - ], - "name": "Redeem", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "newAddress", "type": "address"} - ], - "name": "Deprecate", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "feeBasisPoints", "type": "uint256"}, - {"indexed": false, "name": "maxFee", "type": "uint256"} - ], - "name": "Params", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "_blackListedUser", "type": "address"}, - {"indexed": false, "name": "_balance", "type": "uint256"} - ], - "name": "DestroyedBlackFunds", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "_user", "type": "address"} - ], - "name": "AddedBlackList", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": false, "name": "_user", "type": "address"} - ], - "name": "RemovedBlackList", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": true, "name": "owner", "type": "address"}, - {"indexed": true, "name": "spender", "type": "address"}, - {"indexed": false, "name": "value", "type": "uint256"} - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - {"indexed": true, "name": "from", "type": "address"}, - {"indexed": true, "name": "to", "type": "address"}, - {"indexed": false, "name": "value", "type": "uint256"} - ], - "name": "Transfer", - "type": "event" - }, - {"anonymous": false, "inputs": [], "name": "Pause", "type": "event"}, - {"anonymous": false, "inputs": [], "name": "Unpause", "type": "event"} - ]; - - static const getFilterChangesAbi = [ - 'event Transfer(address indexed from, address indexed to, uint amount)', + } ]; } diff --git a/example/lib/utils/crypto/eip155.dart b/example/lib/utils/crypto/eip155.dart index a2908c53..f77a5eb7 100644 --- a/example/lib/utils/crypto/eip155.dart +++ b/example/lib/utils/crypto/eip155.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -// ignore: depend_on_referenced_packages -import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; import 'package:web3modal_flutter/web3modal_flutter.dart'; import 'package:walletconnect_flutter_dapp/models/eth/ethereum_transaction.dart'; @@ -201,51 +200,105 @@ class EIP155 { ); } - static Future testContractCall({ + static Future callSmartContract({ required W3MService w3mService, - }) async { - // Create a Web3Client by passing a chain rpcUrl and an http client - final ethChain = W3MChainPresets.chains['1']!; - final ethClient = Web3Client(ethChain.rpcUrl, http.Client()); - + required String action, + }) { // Create DeployedContract object using contract's ABI and address final deployedContract = DeployedContract( ContractAbi.fromJson( - jsonEncode(ContractDetails.readContractAbi), - 'TetherToken', + jsonEncode(SepoliaTestContract.readContractAbi), + 'Alfreedoms', ), - EthereumAddress.fromHex(ContractDetails.contractAddress), + EthereumAddress.fromHex(SepoliaTestContract.contractAddress), ); - // Query contract's functions - final nameFunction = deployedContract.function('name'); - final totalSupplyFunction = deployedContract.function('totalSupply'); - final balanceFunction = deployedContract.function('balanceOf'); - - final nameResult = await ethClient.call( - contract: deployedContract, - function: nameFunction, - params: [], - ); + switch (action) { + case 'read': + return _readSmartContract( + w3mService: w3mService, + rpcUrl: 'https://ethereum-sepolia.publicnode.com', + contract: deployedContract, + address: w3mService.session!.address!, + ); + case 'write': + return _writeToSmartContract( + w3mService: w3mService, + rpcUrl: 'https://ethereum-sepolia.publicnode.com', + address: w3mService.session!.address!, + topic: w3mService.session!.topic!, + chainId: 'eip155:11155111', + contract: deployedContract, + transaction: Transaction( + from: EthereumAddress.fromHex(w3mService.session!.address!), + to: EthereumAddress.fromHex( + '0x59e2f66C0E96803206B6486cDb39029abAE834c0'), + value: EtherAmount.fromInt(EtherUnit.finney, 10), // == 0.010 + ), + ); + default: + return Future.value(); + } + } - final totalSupply = await ethClient.call( - contract: deployedContract, - function: totalSupplyFunction, - params: [], - ); + static Future _readSmartContract({ + required W3MService w3mService, + required String rpcUrl, + required String address, + required DeployedContract contract, + }) async { + final results = await Future.wait([ + // results[0] + w3mService.requestReadContract( + deployedContract: contract, + functionName: 'name', + rpcUrl: rpcUrl, + ), + // results[1] + w3mService.requestReadContract( + deployedContract: contract, + functionName: 'totalSupply', + rpcUrl: rpcUrl, + ), + // results[2] + w3mService.requestReadContract( + deployedContract: contract, + functionName: 'balanceOf', + rpcUrl: rpcUrl, + parameters: [ + EthereumAddress.fromHex(address), + ], + ), + ]); - final balanceOf = await ethClient.call( - contract: deployedContract, - function: balanceFunction, - params: [ - EthereumAddress.fromHex(w3mService.session!.address!), - ], - ); + final oCcy = NumberFormat("#,##0.00", "en_US"); + final name = results[0].toString(); + final total = results[1] / BigInt.from(1000000000000000000); + final balance = results[2] / BigInt.from(1000000000000000000); return { - 'name': '${nameResult.first}', - 'totalSupply': '${totalSupply.first}', - 'balance': '${balanceOf.first}', + 'name': name, + 'totalSupply': oCcy.format(total), + 'balance': oCcy.format(balance), }; } + + static Future _writeToSmartContract({ + required W3MService w3mService, + required String rpcUrl, + required String topic, + required String chainId, + required String address, + required DeployedContract contract, + required Transaction transaction, + }) async { + return await w3mService.requestWriteContract( + topic: topic, + chainId: chainId, + rpcUrl: rpcUrl, + deployedContract: contract, + functionName: 'transfer', + transaction: transaction, + ); + } } diff --git a/example/lib/utils/crypto/web3dart_extension.dart b/example/lib/utils/crypto/web3dart_extension.dart deleted file mode 100644 index c677e99f..00000000 --- a/example/lib/utils/crypto/web3dart_extension.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:web3modal_flutter/web3modal_flutter.dart'; - -extension TransactionX on Transaction { - Map toJson({ - String? fromAddress, - }) { - return { - 'from': fromAddress ?? from?.hex, - 'to': to?.hex, - 'gas': maxGas != null ? '0x${maxGas!.toRadixString(16)}' : null, - 'gasPrice': '0x${gasPrice?.getInWei.toRadixString(16) ?? '0'}', - 'value': '0x${value?.getInWei.toRadixString(16) ?? '0'}', - 'data': data != null ? bytesToHex(data!) : null, - 'nonce': nonce, - }; - } -} diff --git a/example/lib/widgets/session_widget.dart b/example/lib/widgets/session_widget.dart index e1eb669b..7fd77c89 100644 --- a/example/lib/widgets/session_widget.dart +++ b/example/lib/widgets/session_widget.dart @@ -256,40 +256,87 @@ class SessionWidgetState extends State { ); } - if (chainMetadata.w3mChainInfo.chainId == '1') { - children.add( - Container( - height: StyleConstants.linear40, - width: double.infinity, - margin: const EdgeInsets.symmetric(vertical: StyleConstants.linear8), - child: ElevatedButton( - onPressed: () async { - final future = EIP155.testContractCall( - w3mService: widget.w3mService, - ); - MethodDialog.show(context, 'Test TetherToken Contract', future); - }, - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Colors.orange), - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(StyleConstants.linear8), - ), + children.add(const Divider()); + final onSepolia = chainMetadata.w3mChainInfo.chainId == '11155111'; + if (!onSepolia) { + children.add(const Text('Connect to Sepolia to Test')); + } + + children.addAll([ + Container( + height: StyleConstants.linear40, + width: double.infinity, + margin: const EdgeInsets.symmetric(vertical: StyleConstants.linear8), + child: ElevatedButton( + onPressed: onSepolia + ? () async { + final future = EIP155.callSmartContract( + w3mService: widget.w3mService, + action: 'read', + ); + MethodDialog.show(context, 'Test Contract (Read)', future); + } + : null, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.disabled)) { + return Colors.grey; + } + return Colors.orange; + }), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(StyleConstants.linear8), ), ), - child: Text( - 'Test TetherToken Contract', - style: Web3ModalTheme.getDataOf(context) - .textStyles - .small600 - .copyWith( - color: Web3ModalTheme.colorsOf(context).foreground100, - ), + ), + child: Text( + 'Test Contract (Read)', + style: + Web3ModalTheme.getDataOf(context).textStyles.small600.copyWith( + color: Web3ModalTheme.colorsOf(context).foreground100, + ), + ), + ), + ), + Container( + height: StyleConstants.linear40, + width: double.infinity, + margin: const EdgeInsets.symmetric(vertical: StyleConstants.linear8), + child: ElevatedButton( + onPressed: onSepolia + ? () async { + final future = EIP155.callSmartContract( + w3mService: widget.w3mService, + action: 'write', + ); + MethodDialog.show(context, 'Test Contract (Write)', future); + widget.launchRedirect(); + } + : null, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.resolveWith((states) { + if (states.contains(MaterialState.disabled)) { + return Colors.grey; + } + return Colors.orange; + }), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(StyleConstants.linear8), + ), ), ), + child: Text( + 'Test Contract (Write)', + style: + Web3ModalTheme.getDataOf(context).textStyles.small600.copyWith( + color: Web3ModalTheme.colorsOf(context).foreground100, + ), + ), ), - ); - } + ), + ]); return children; } diff --git a/example/pubspec.lock b/example/pubspec.lock index a84851dc..4fc94700 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -456,6 +456,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.17" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" io: dependency: transitive description: @@ -1065,10 +1073,10 @@ packages: dependency: transitive description: name: walletconnect_flutter_v2 - sha256: "419f58dbb5b636f2907b1e74a27e5a4da08c5c320e40fee21b69b65f852769ce" + sha256: f3c90f6eceb130fefcc6b6e22a28ecc971612c90e91fbfaaafbd73c2178db8c1 url: "https://pub.dev" source: hosted - version: "2.1.14" + version: "2.2.0-beta01" watcher: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 86eec0c6..978be57c 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: cupertino_icons: ^1.0.2 fl_toast: ^3.1.0 shared_preferences: ^2.2.0 + intl: ^0.19.0 web3modal_flutter: path: ../ diff --git a/lib/services/w3m_service/i_w3m_service.dart b/lib/services/w3m_service/i_w3m_service.dart index 19b7a1f5..af63d0dc 100644 --- a/lib/services/w3m_service/i_w3m_service.dart +++ b/lib/services/w3m_service/i_w3m_service.dart @@ -123,6 +123,24 @@ abstract class IW3MService with ChangeNotifier { /// If there is no session, this does nothing. Future disconnect({bool disconnectAllSessions = true}); + Future requestReadContract({ + required DeployedContract deployedContract, + required String functionName, + required String rpcUrl, + List parameters = const [], + }); + + Future requestWriteContract({ + required String topic, + required String chainId, + required String rpcUrl, + required DeployedContract deployedContract, + required String functionName, + required Transaction transaction, + String? method, + List parameters = const [], + }); + /// Make a request Future request({ required String topic, diff --git a/lib/services/w3m_service/w3m_service.dart b/lib/services/w3m_service/w3m_service.dart index 6e0c16a9..9348c6e9 100644 --- a/lib/services/w3m_service/w3m_service.dart +++ b/lib/services/w3m_service/w3m_service.dart @@ -613,6 +613,52 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { } } + @override + Future requestReadContract({ + required DeployedContract deployedContract, + required String functionName, + required String rpcUrl, + List parameters = const [], + }) async { + try { + return await _web3App.requestReadContract( + deployedContract: deployedContract, + functionName: functionName, + rpcUrl: rpcUrl, + parameters: parameters, + ); + } catch (e) { + rethrow; + } + } + + @override + Future requestWriteContract({ + required String topic, + required String chainId, + required String rpcUrl, + required DeployedContract deployedContract, + required String functionName, + required Transaction transaction, + String? method, + List parameters = const [], + }) async { + try { + return await _web3App.requestWriteContract( + topic: topic, + chainId: chainId, + rpcUrl: rpcUrl, + deployedContract: deployedContract, + functionName: functionName, + transaction: transaction, + method: method, + parameters: parameters, + ); + } catch (e) { + rethrow; + } + } + @override Future request({ required String topic, diff --git a/pubspec.lock b/pubspec.lock index ee2b28a5..9af08f19 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1049,10 +1049,10 @@ packages: dependency: "direct main" description: name: walletconnect_flutter_v2 - sha256: "419f58dbb5b636f2907b1e74a27e5a4da08c5c320e40fee21b69b65f852769ce" + sha256: f3c90f6eceb130fefcc6b6e22a28ecc971612c90e91fbfaaafbd73c2178db8c1 url: "https://pub.dev" source: hosted - version: "2.1.14" + version: "2.2.0-beta01" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 010ffe40..652c9a08 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,7 +22,8 @@ dependencies: qr_flutter_wc: ^0.0.3 shimmer: ^3.0.0 url_launcher: ^6.2.3 - walletconnect_flutter_v2: ^2.1.14 + # walletconnect_flutter_v2: ^2.1.14 + walletconnect_flutter_v2: ^2.2.0-beta01 dev_dependencies: build_runner: ^2.4.7 diff --git a/test/mock_classes.mocks.dart b/test/mock_classes.mocks.dart index e92091c1..5589602f 100644 --- a/test/mock_classes.mocks.dart +++ b/test/mock_classes.mocks.dart @@ -753,6 +753,54 @@ class MockW3MService extends _i1.Mock implements _i3.W3MService { returnValueForMissingStub: null, ); @override + _i14.Future requestReadContract({ + required _i3.DeployedContract? deployedContract, + required String? functionName, + required String? rpcUrl, + List? parameters = const [], + }) => + (super.noSuchMethod( + Invocation.method( + #requestReadContract, + [], + { + #deployedContract: deployedContract, + #functionName: functionName, + #rpcUrl: rpcUrl, + #parameters: parameters, + }, + ), + returnValue: _i14.Future.value(), + ) as _i14.Future); + @override + _i14.Future requestWriteContract({ + required String? topic, + required String? chainId, + required String? rpcUrl, + required _i3.DeployedContract? deployedContract, + required String? functionName, + required _i3.Transaction? transaction, + String? method, + List? parameters = const [], + }) => + (super.noSuchMethod( + Invocation.method( + #requestWriteContract, + [], + { + #topic: topic, + #chainId: chainId, + #rpcUrl: rpcUrl, + #deployedContract: deployedContract, + #functionName: functionName, + #transaction: transaction, + #method: method, + #parameters: parameters, + }, + ), + returnValue: _i14.Future.value(), + ) as _i14.Future); + @override _i14.Future request({ required String? topic, required String? chainId, @@ -1308,6 +1356,54 @@ class MockWeb3App extends _i1.Mock implements _i3.Web3App { returnValue: _i14.Future.value(), ) as _i14.Future); @override + _i14.Future requestReadContract({ + required _i3.DeployedContract? deployedContract, + required String? functionName, + required String? rpcUrl, + List? parameters = const [], + }) => + (super.noSuchMethod( + Invocation.method( + #requestReadContract, + [], + { + #deployedContract: deployedContract, + #functionName: functionName, + #rpcUrl: rpcUrl, + #parameters: parameters, + }, + ), + returnValue: _i14.Future.value(), + ) as _i14.Future); + @override + _i14.Future requestWriteContract({ + required String? topic, + required String? chainId, + required String? rpcUrl, + required _i3.DeployedContract? deployedContract, + required String? functionName, + required _i3.Transaction? transaction, + String? method, + List? parameters = const [], + }) => + (super.noSuchMethod( + Invocation.method( + #requestWriteContract, + [], + { + #topic: topic, + #chainId: chainId, + #rpcUrl: rpcUrl, + #deployedContract: deployedContract, + #functionName: functionName, + #transaction: transaction, + #method: method, + #parameters: parameters, + }, + ), + returnValue: _i14.Future.value(), + ) as _i14.Future); + @override void registerEventHandler({ required String? chainId, required String? event, From 1563eff9ec9888f3c5867c1d2e18aeba9c2d687c Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Fri, 2 Feb 2024 11:21:00 +0100 Subject: [PATCH 4/6] added support for more sample wallets --- .../android/app/src/main/AndroidManifest.xml | 4 +- example/ios/Runner/Info.plist | 2 +- .../explorer_service/explorer_service.dart | 4 +- .../models/wc_sample_wallets.dart | 111 ++++++++++++------ 4 files changed, 81 insertions(+), 40 deletions(-) diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 76255dc3..c3b46f34 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -48,8 +48,10 @@ - + + + okex trust thorwallet - leapcosmos everspace cosmostation coinwallet @@ -91,6 +90,7 @@ argent walletapp wcflutterwallet + rn-web3wallet LSRequiresIPhoneOS diff --git a/lib/services/explorer_service/explorer_service.dart b/lib/services/explorer_service/explorer_service.dart index fa7257ae..153188f8 100644 --- a/lib/services/explorer_service/explorer_service.dart +++ b/lib/services/explorer_service/explorer_service.dart @@ -143,9 +143,9 @@ class ExplorerService implements IExplorerService { final platform = platformUtils.instance.getPlatformExact().name; final platformName = platform.toString().toLowerCase(); List sampleWallets = []; - for (var sampleWallet in WCSampleWallets.wallets.values) { + for (var sampleWallet in WCSampleWallets.getSampleWallets(platformName)) { final data = WCSampleWallets.nativeData[sampleWallet.listing.id]; - final schema = data?[platformName]?.schema ?? ''; + final schema = (data?[platformName]! as NativeAppData).schema ?? ''; final installed = await urlUtils.instance.isInstalled(schema); if (installed) { sampleWallet = sampleWallet.copyWith(installed: true); diff --git a/lib/services/explorer_service/models/wc_sample_wallets.dart b/lib/services/explorer_service/models/wc_sample_wallets.dart index bcc10cdf..0433640a 100644 --- a/lib/services/explorer_service/models/wc_sample_wallets.dart +++ b/lib/services/explorer_service/models/wc_sample_wallets.dart @@ -3,7 +3,10 @@ import 'package:web3modal_flutter/web3modal_flutter.dart'; class WCSampleWallets { static final nativeData = { + // Swift Wallet '123456789012345678901234567890': { + 'name': 'Wallet (Swift)', + 'platform': ['ios'], 'ios': NativeAppData( id: '123456789012345678901234567890', schema: 'walletapp://', @@ -13,52 +16,88 @@ class WCSampleWallets { schema: 'com.walletconnect.sample.wallet', ), }, + // Flutter Wallet '123456789012345678901234567891': { + 'name': 'Wallet (Flutter)', + 'platform': ['ios', 'android'], 'ios': NativeAppData( - id: '123456789012345678901234567890', + id: '123456789012345678901234567891', schema: 'wcflutterwallet://', ), 'android': NativeAppData( - id: '123456789012345678901234567890', + id: '123456789012345678901234567891', schema: 'com.walletconnect.flutterwallet', ), - } + }, + // React Native Wallet + '123456789012345678901234567892': { + 'name': 'Wallet (RN)', + 'platform': ['ios', 'android'], + 'ios': NativeAppData( + id: '123456789012345678901234567892', + schema: 'rn-web3wallet://', + ), + 'android': NativeAppData( + id: '123456789012345678901234567892', + schema: 'com.walletconnect.web3wallet.rnsample', + ), + }, + // Kotlin Wallet + '123456789012345678901234567893': { + 'name': 'Wallet (Kotlin)', + 'platform': ['android'], + 'ios': NativeAppData( + id: '123456789012345678901234567893', + schema: 'kotlin-web3wallet://', + ), + 'android': NativeAppData( + id: '123456789012345678901234567893', + schema: 'com.walletconnect.sample.wallet', + ), + }, + // // Kotlin Wallet Internal + // '123456789012345678901234567894': { + // 'name': 'Wallet (Kotlin Internal)', + // 'platform': ['android'], + // 'ios': NativeAppData( + // id: '123456789012345678901234567894', + // schema: 'kotlin-web3wallet://', + // ), + // 'android': NativeAppData( + // id: '123456789012345678901234567894', + // schema: 'com.walletconnect.sample.wallet.internal', + // ), + // } }; - static final wallets = { - 'ios': W3MWalletInfo( - listing: Listing.fromJson({ - 'id': '123456789012345678901234567890', - 'name': 'Wallet (Swift)', - 'homepage': 'https://walletconnect.com', - 'image_id': _walletImage, - 'order': 30, - 'mobile_link': 'walletapp://', - 'app_store': 'https://apps.apple.com/app/apple-store/', - 'play_store': - '$_playstoreUrl${nativeData["123456789012345678901234567890"]?["android"]?.schema}', - }), - installed: false, - recent: false, - ), - 'flutter': W3MWalletInfo( - listing: Listing.fromJson({ - 'id': '123456789012345678901234567891', - 'name': 'Wallet (Flutter)', - 'homepage': 'https://walletconnect.com', - 'image_id': _walletImage, - 'order': 30, - 'mobile_link': 'wcflutterwallet://', - 'app_store': 'https://apps.apple.com/app/apple-store/', - 'play_store': - '$_playstoreUrl${nativeData["123456789012345678901234567891"]?["android"]?.schema}', - }), - installed: false, - recent: false, - ), - }; + static List getSampleWallets(String platform) { + final wallets = nativeData.entries.map((entry) { + final packageId = (entry.value['android']! as NativeAppData).schema; + final schema = (entry.value['ios']! as NativeAppData).schema; + final platforms = entry.value['platform']! as List; + final name = entry.value['name']! as String; + if (platforms.contains(platform)) { + return W3MWalletInfo( + listing: Listing.fromJson({ + 'id': entry.key, + 'name': name, + 'homepage': 'https://walletconnect.com', + 'image_id': _walletImage, + 'order': 10, + 'mobile_link': schema, + 'app_store': + 'https://apps.apple.com/app/apple-store/id${entry.key}', + 'play_store': + 'https://play.google.com/store/apps/details?id=$packageId', + }), + installed: false, + recent: false, + ); + } + }).toList(); + return wallets.whereType().toList(); + } - static const _playstoreUrl = 'https://play.google.com/store/apps/details?id='; static const _walletImage = 'https://docs.walletconnect.com/assets/images/web3walletLogo-54d3b546146931ceaf47a3500868a73a.png'; } From 697990401904e65797289e5540c564981e63c52d Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Fri, 2 Feb 2024 11:29:27 +0100 Subject: [PATCH 5/6] version preparation --- CHANGELOG.md | 4 ++++ example/android/gradle.properties | 4 ++-- example/ios/Runner.xcodeproj/project.pbxproj | 12 ++++++------ example/ios/Runner/Info.plist | 4 ++-- example/pubspec.lock | 2 +- example/pubspec.yaml | 2 +- lib/version.dart | 2 +- pubspec.yaml | 2 +- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0159edaf..81496f82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.1.1-beta01 + +- Better Smart Contract interactions + ## 3.1.0 - Coinbase Wallet integration diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 35c52176..cc45d321 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -versionName=3.1.0 -versionCode=30 +versionName=3.1.1 +versionCode=31 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 9ac3c3ce..5597e309 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -470,7 +470,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22; ENABLE_BITCODE = NO; @@ -496,7 +496,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests; @@ -514,7 +514,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests; @@ -530,7 +530,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.web3modal.flutterExample.RunnerTests; @@ -655,7 +655,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22; ENABLE_BITCODE = NO; @@ -686,7 +686,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 30; + CURRENT_PROJECT_VERSION = 31; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22; ENABLE_BITCODE = NO; diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 77385d93..531556a5 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.1.0 + 3.1.1 CFBundleSignature ???? CFBundleURLTypes @@ -36,7 +36,7 @@ CFBundleVersion - 30 + 31 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/example/pubspec.lock b/example/pubspec.lock index 4fc94700..0af8e8df 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1107,7 +1107,7 @@ packages: path: ".." relative: true source: path - version: "3.1.0" + version: "3.1.1-beta01" web_socket_channel: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 978be57c..1b7788f9 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: A dApp showing how to use WalletConnect v2 with Flutter publish_to: "none" -version: 3.1.0 +version: 3.1.1 environment: sdk: ">=3.0.1 <4.0.0" diff --git a/lib/version.dart b/lib/version.dart index d006dce1..e6cc46ed 100644 --- a/lib/version.dart +++ b/lib/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '3.1.0'; +const packageVersion = '3.1.1-beta01'; diff --git a/pubspec.yaml b/pubspec.yaml index 652c9a08..72e58e05 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: web3modal_flutter description: "WalletConnect Web3Modal: Simple, intuitive wallet login. With this drop-in UI SDK, enable any wallet's users to seamlessly log in to your app and enjoy a unified experience" -version: 3.1.0 +version: 3.1.1-beta01 repository: https://github.com/WalletConnect/Web3ModalFlutter environment: From 115a4f2fbe380c8d13e2060a069b553ecab84381 Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Fri, 2 Feb 2024 11:31:04 +0100 Subject: [PATCH 6/6] minor change --- example/lib/home_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/lib/home_page.dart b/example/lib/home_page.dart index 89744596..0fee3dae 100644 --- a/example/lib/home_page.dart +++ b/example/lib/home_page.dart @@ -216,7 +216,7 @@ final _sepolia = W3MChainInfo( tokenName: 'ETH', rpcUrl: 'https://ethereum-sepolia.publicnode.com', blockExplorer: W3MBlockExplorer( - name: 'Arbitrum Sepolia Testnet', + name: 'Sepolia Etherscan', url: 'https://sepolia.etherscan.io/', ), );