From 18a311082b3e3f8ff72f3c3046ee280b2d0a1368 Mon Sep 17 00:00:00 2001 From: Alfreedom <00tango.bromine@icloud.com> Date: Mon, 27 May 2024 11:43:11 +0200 Subject: [PATCH] minor example refactor --- example/lib/utils/crypto/eip155.dart | 142 +++++++++----------- lib/services/w3m_service/i_w3m_service.dart | 8 +- lib/services/w3m_service/w3m_service.dart | 49 ++++--- test/mock_classes.mocks.dart | 4 +- 4 files changed, 99 insertions(+), 104 deletions(-) diff --git a/example/lib/utils/crypto/eip155.dart b/example/lib/utils/crypto/eip155.dart index 8be13e6d..6a2122ce 100644 --- a/example/lib/utils/crypto/eip155.dart +++ b/example/lib/utils/crypto/eip155.dart @@ -1,5 +1,4 @@ import 'dart:convert'; -import 'dart:math'; import 'package:intl/intl.dart'; import 'package:walletconnect_flutter_dapp/utils/crypto/smart_contracts/usdt_contract.dart'; import 'package:web3modal_flutter/web3modal_flutter.dart'; @@ -76,171 +75,158 @@ class EIP155 { final cid = int.parse(chainId.split(':')[1]); switch (method) { case EIP155UIMethods.requestAccounts: - return w3mService.request( - topic: topic, - chainId: chainId, - request: SessionRequestParams( - method: method.name, - params: [], - ), + return requestAccounts( + w3mService: w3mService, ); case EIP155UIMethods.personalSign: return personalSign( w3mService: w3mService, - topic: topic, - chainId: chainId, - address: address, message: testSignData, ); case EIP155UIMethods.ethSignTypedDataV3: return ethSignTypedDataV3( w3mService: w3mService, - topic: topic, - chainId: chainId, - address: address, data: jsonEncode(typeDataV3(cid)), ); case EIP155UIMethods.ethSignTypedData: return ethSignTypedData( w3mService: w3mService, - topic: topic, - chainId: chainId, - address: address, data: jsonEncode(typedData()), ); case EIP155UIMethods.ethSignTypedDataV4: return ethSignTypedDataV4( w3mService: w3mService, - topic: topic, - chainId: chainId, - address: address, data: jsonEncode(typeDataV4(cid)), ); case EIP155UIMethods.ethSignTransaction: case EIP155UIMethods.ethSendTransaction: return ethSendTransaction( w3mService: w3mService, - topic: topic, - chainId: chainId, - method: method.name, transaction: Transaction( from: EthereumAddress.fromHex(address), to: EthereumAddress.fromHex( '0x59e2f66C0E96803206B6486cDb39029abAE834c0', ), value: EtherAmount.fromInt(EtherUnit.finney, 11), // == 0.011 - nonce: Random().nextInt(10000), ), + method: method, ); case EIP155UIMethods.walletWatchAsset: return walletWatchAsset( w3mService: w3mService, - topic: topic, - chainId: chainId, - method: method.name, ); } } + static Future requestAccounts({ + required W3MService w3mService, + }) async { + return await w3mService.request( + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, + request: SessionRequestParams( + method: EIP155UIMethods.requestAccounts.name, + params: [], + ), + ); + } + static Future personalSign({ required W3MService w3mService, - required String topic, - required String chainId, - required String address, required String message, }) async { final bytes = utf8.encode(message); final encoded = hex.encode(bytes); return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( method: EIP155UIMethods.personalSign.name, - params: ['0x$encoded', address], + params: [ + '0x$encoded', + w3mService.session!.address!, + ], ), ); } static Future ethSignTypedData({ required W3MService w3mService, - required String topic, - required String chainId, - required String address, required String data, }) async { return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( method: EIP155UIMethods.ethSignTypedData.name, - params: [data, address], + params: [ + data, + w3mService.session!.address!, + ], ), ); } static Future ethSignTypedDataV3({ required W3MService w3mService, - required String topic, - required String chainId, - required String address, required String data, }) async { return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( method: EIP155UIMethods.ethSignTypedDataV3.name, - params: [data, address], + params: [ + data, + w3mService.session!.address!, + ], ), ); } static Future ethSignTypedDataV4({ required W3MService w3mService, - required String topic, - required String chainId, - required String address, required String data, }) async { return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( method: EIP155UIMethods.ethSignTypedDataV4.name, - params: [data, address], + params: [ + data, + w3mService.session!.address!, + ], ), ); } static Future ethSendTransaction({ required W3MService w3mService, - required String topic, - required String chainId, - required String method, required Transaction transaction, + required EIP155UIMethods method, }) async { return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( - method: method, - params: [transaction.toJson()], + method: method.name, + params: [ + transaction.toJson(), + ], ), ); } static Future walletWatchAsset({ required W3MService w3mService, - required String topic, - required String chainId, - required String method, }) async { return await w3mService.request( - topic: topic, - chainId: chainId, + topic: w3mService.session!.topic, + chainId: w3mService.selectedChain!.chainId, request: SessionRequestParams( - method: method, + method: EIP155UIMethods.walletWatchAsset.name, params: { "type": "ERC20", "options": { @@ -255,6 +241,7 @@ class EIP155 { ); } + // Example of calling `transfer` function from AAVE token Smart Contract static Future callTestSmartContract({ required W3MService w3mService, required String action, @@ -272,22 +259,21 @@ class EIP155 { case 'read': return _readSmartContract( w3mService: w3mService, - rpcUrl: w3mService.selectedChain!.rpcUrl, contract: deployedContract, - address: w3mService.session!.address!, ); case 'write': + // we first call `decimals` function, which is a read function, + // to check how much decimal we need to use to parse the amount value final decimals = await w3mService.requestReadContract( deployedContract: deployedContract, functionName: 'decimals', - rpcUrl: w3mService.selectedChain!.rpcUrl, ); final d = (decimals.first as BigInt); final requestValue = _formatValue(0.01, decimals: d); + // now we call `transfer` write function with the parsed value. return w3mService.requestWriteContract( - topic: w3mService.session?.topic ?? '', + topic: w3mService.session!.topic, chainId: w3mService.selectedChain!.namespace, - rpcUrl: w3mService.selectedChain!.rpcUrl, deployedContract: deployedContract, functionName: 'transfer', transaction: Transaction( @@ -325,6 +311,7 @@ class EIP155 { } } + // Example of calling `transfer` function from USDT token Smart Contract static Future callUSDTSmartContract({ required W3MService w3mService, required String action, @@ -342,22 +329,21 @@ class EIP155 { case 'read': return _readSmartContract( w3mService: w3mService, - rpcUrl: w3mService.selectedChain!.rpcUrl, contract: deployedContract, - address: w3mService.session!.address!, ); case 'write': + // we first call `decimals` function, which is a read function, + // to check how much decimal we need to use to parse the amount value final decimals = await w3mService.requestReadContract( deployedContract: deployedContract, functionName: 'decimals', - rpcUrl: w3mService.selectedChain!.rpcUrl, ); final d = (decimals.first as BigInt); final requestValue = _formatValue(0.23, decimals: d); + // now we call `transfer` write function with the parsed value. return w3mService.requestWriteContract( - topic: w3mService.session?.topic ?? '', + topic: w3mService.session!.topic, chainId: w3mService.selectedChain!.namespace, - rpcUrl: w3mService.selectedChain!.rpcUrl, deployedContract: deployedContract, functionName: 'transfer', transaction: Transaction( @@ -377,8 +363,6 @@ class EIP155 { static Future _readSmartContract({ required W3MService w3mService, - required String rpcUrl, - required String address, required DeployedContract contract, }) async { final results = await Future.wait([ @@ -386,28 +370,24 @@ class EIP155 { 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), + EthereumAddress.fromHex(w3mService.session!.address!), ], ), // results[4] w3mService.requestReadContract( deployedContract: contract, functionName: 'decimals', - rpcUrl: rpcUrl, ), ]); diff --git a/lib/services/w3m_service/i_w3m_service.dart b/lib/services/w3m_service/i_w3m_service.dart index 379e4c25..a73d4183 100644 --- a/lib/services/w3m_service/i_w3m_service.dart +++ b/lib/services/w3m_service/i_w3m_service.dart @@ -108,14 +108,14 @@ abstract class IW3MService with ChangeNotifier { Future> requestReadContract({ required DeployedContract deployedContract, required String functionName, - required String rpcUrl, + @Deprecated('This is not needed anymore') String? rpcUrl, List parameters = const [], }); Future requestWriteContract({ - required String topic, + required String? topic, required String chainId, - required String rpcUrl, + @Deprecated('This is not needed anymore') String? rpcUrl, required DeployedContract deployedContract, required String functionName, required Transaction transaction, @@ -125,7 +125,7 @@ abstract class IW3MService with ChangeNotifier { /// Make a request Future request({ - required String topic, + required String? topic, required String chainId, String? switchToChainId, required SessionRequestParams request, diff --git a/lib/services/w3m_service/w3m_service.dart b/lib/services/w3m_service/w3m_service.dart index 5e6733f3..045b232f 100644 --- a/lib/services/w3m_service/w3m_service.dart +++ b/lib/services/w3m_service/w3m_service.dart @@ -858,14 +858,14 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { Future> requestReadContract({ required DeployedContract deployedContract, required String functionName, - required String rpcUrl, + @Deprecated('This is not needed anymore') String? rpcUrl, List parameters = const [], }) async { try { return await _web3App.requestReadContract( deployedContract: deployedContract, functionName: functionName, - rpcUrl: rpcUrl, + rpcUrl: selectedChain!.rpcUrl, parameters: parameters, ); } catch (e) { @@ -875,9 +875,9 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { @override Future requestWriteContract({ - required String topic, + required String? topic, required String chainId, - required String rpcUrl, + @Deprecated('This is not needed anymore') String? rpcUrl, required DeployedContract deployedContract, required String functionName, required Transaction transaction, @@ -914,7 +914,7 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { @override Future request({ - required String topic, + required String? topic, required String chainId, required SessionRequestParams request, String? switchToChainId, @@ -922,22 +922,38 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { if (_currentSession == null) { throw W3MServiceException('Session is null'); } + String requestChainId = chainId; + + final isValidChainId = NamespaceUtils.isValidChainId(chainId); + if (!isValidChainId) { + if (selectedChain!.namespace.contains(chainId)) { + requestChainId = selectedChain!.namespace; + } else { + throw Errors.getSdkError( + Errors.UNSUPPORTED_CHAINS, + context: 'chainId should conform to "namespace:chainId" format', + ); + } + } + // + _logger.d( + '[$runtimeType] request, chainId: $requestChainId, ${jsonEncode(request.toJson())}'); try { if (_currentSession!.sessionService.isMagic) { return await magicService.instance.request( - chainId: chainId, + chainId: requestChainId, request: request, ); } if (_currentSession!.sessionService.isCoinbase) { return await cbRequest( - chainId: switchToChainId ?? chainId, + chainId: switchToChainId ?? requestChainId, request: request, ); } return await _web3App.request( - topic: topic, - chainId: chainId, + topic: topic!, + chainId: requestChainId, request: request, ); } catch (e) { @@ -1096,15 +1112,14 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { if (_currentSession?.sessionService.isMagic == true) { return selectChain(newChain); } - final chainId = _currentSelectedChain?.chainId; - final currentChainId = '${StringConstants.namespace}:$chainId'; - final newChainId = '${StringConstants.namespace}:${newChain.chainId}'; + final currentChainId = _currentSelectedChain!.namespace; + final newChainId = newChain.namespace; _logger.i('[$runtimeType] requesting switch to chain $newChainId'); try { final response = await request( topic: _currentSession?.topic ?? '', chainId: currentChainId, - switchToChainId: newChain.chainId, + switchToChainId: newChainId, request: SessionRequestParams( method: MethodsConstants.walletSwitchEthChain, params: [ @@ -1132,14 +1147,14 @@ class W3MService with ChangeNotifier, CoinbaseService implements IW3MService { @override Future requestAddChain(W3MChainInfo newChain) async { final topic = _currentSession?.topic ?? ''; - final currentId = _currentSelectedChain!.chainId; - final currentChainId = '${StringConstants.namespace}:$currentId'; - _logger.i('[$runtimeType] requesting add chain ${newChain.namespace}'); + final currentChainId = _currentSelectedChain!.namespace; + final newChainId = newChain.namespace; + _logger.i('[$runtimeType] requesting switch to chain $newChainId'); try { final response = await request( topic: topic, chainId: currentChainId, - switchToChainId: newChain.chainId, + switchToChainId: newChainId, request: SessionRequestParams( method: MethodsConstants.walletAddEthChain, params: [newChain.toJson()], diff --git a/test/mock_classes.mocks.dart b/test/mock_classes.mocks.dart index 9de96b1e..9bfece6d 100644 --- a/test/mock_classes.mocks.dart +++ b/test/mock_classes.mocks.dart @@ -787,7 +787,7 @@ class MockW3MService extends _i1.Mock implements _i3.W3MService { _i14.Future> requestReadContract({ required _i3.DeployedContract? deployedContract, required String? functionName, - required String? rpcUrl, + String? rpcUrl, List? parameters = const [], }) => (super.noSuchMethod( @@ -807,7 +807,7 @@ class MockW3MService extends _i1.Mock implements _i3.W3MService { _i14.Future requestWriteContract({ required String? topic, required String? chainId, - required String? rpcUrl, + String? rpcUrl, required _i3.DeployedContract? deployedContract, required String? functionName, required _i3.Transaction? transaction,