diff --git a/CHANGELOG.md b/CHANGELOG.md index 920c1d54..936ea0d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.3.1-beta02 +## 2.3.1 - Added Connectivity check to core and throw exceptions when internet connection is gone - Fix for https://github.com/WalletConnect/WalletConnectFlutterV2/issues/303 (EIP-55 validation for SIWE) diff --git a/example/dapp/ios/Podfile.lock b/example/dapp/ios/Podfile.lock index 8279be30..d0b23efb 100644 --- a/example/dapp/ios/Podfile.lock +++ b/example/dapp/ios/Podfile.lock @@ -1,6 +1,9 @@ PODS: - appcheck (1.0.3): - Flutter + - connectivity_plus (0.0.1): + - Flutter + - FlutterMacOS - Flutter (1.0.0) - flutter_keyboard_visibility (0.0.1): - Flutter @@ -14,6 +17,7 @@ PODS: DEPENDENCIES: - appcheck (from `.symlinks/plugins/appcheck/ios`) + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`) - Flutter (from `Flutter`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) @@ -23,6 +27,8 @@ DEPENDENCIES: EXTERNAL SOURCES: appcheck: :path: ".symlinks/plugins/appcheck/ios" + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/darwin" Flutter: :path: Flutter flutter_keyboard_visibility: @@ -36,6 +42,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: appcheck: e1ab9d4e03736f03e0401554a134d1ed502d7629 + connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c diff --git a/example/dapp/lib/utils/crypto/eip155.dart b/example/dapp/lib/utils/crypto/eip155.dart index 6114c974..29b358c1 100644 --- a/example/dapp/lib/utils/crypto/eip155.dart +++ b/example/dapp/lib/utils/crypto/eip155.dart @@ -129,7 +129,6 @@ class EIP155 { return web3App.requestWriteContract( topic: topic, chainId: sepolia.chainId, - rpcUrl: sepolia.rpc.first, deployedContract: deployedContract, functionName: 'transfer', transaction: Transaction( diff --git a/example/dapp/macos/Flutter/GeneratedPluginRegistrant.swift b/example/dapp/macos/Flutter/GeneratedPluginRegistrant.swift index cc667fc0..a4e08b1e 100644 --- a/example/dapp/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/dapp/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,11 +5,13 @@ import FlutterMacOS import Foundation +import connectivity_plus import package_info_plus import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/example/dapp/pubspec.yaml b/example/dapp/pubspec.yaml index 2567c40c..5c60bea9 100644 --- a/example/dapp/pubspec.yaml +++ b/example/dapp/pubspec.yaml @@ -20,8 +20,10 @@ dependencies: # intl: ^0.19.0 package_info_plus: ^7.0.0 walletconnect_modal_flutter: ^2.1.20 - # walletconnect_flutter_v2: - # path: ../.. + +dependency_overrides: + walletconnect_flutter_v2: + path: ../.. dev_dependencies: flutter_test: diff --git a/example/dapp/windows/flutter/generated_plugin_registrant.cc b/example/dapp/windows/flutter/generated_plugin_registrant.cc index 4f788487..5777988d 100644 --- a/example/dapp/windows/flutter/generated_plugin_registrant.cc +++ b/example/dapp/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,12 @@ #include "generated_plugin_registrant.h" +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/example/dapp/windows/flutter/generated_plugins.cmake b/example/dapp/windows/flutter/generated_plugins.cmake index 88b22e5c..31032063 100644 --- a/example/dapp/windows/flutter/generated_plugins.cmake +++ b/example/dapp/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + connectivity_plus url_launcher_windows ) diff --git a/example/wallet/lib/pages/settings_page.dart b/example/wallet/lib/pages/settings_page.dart index 3414d80b..b3e77ce6 100644 --- a/example/wallet/lib/pages/settings_page.dart +++ b/example/wallet/lib/pages/settings_page.dart @@ -616,8 +616,11 @@ class __DataContainerState extends State<_DataContainer> { ], ), ImageFiltered( - imageFilter: - ImageFilter.blur(sigmaX: blurValue, sigmaY: blurValue), + imageFilter: ImageFilter.blur( + sigmaX: blurValue, + sigmaY: blurValue, + tileMode: TileMode.decal, + ), child: Text( widget.data, style: const TextStyle( diff --git a/lib/apis/sign_api/i_sign_client.dart b/lib/apis/sign_api/i_sign_client.dart index b0dc519a..3aa30669 100644 --- a/lib/apis/sign_api/i_sign_client.dart +++ b/lib/apis/sign_api/i_sign_client.dart @@ -104,7 +104,6 @@ abstract class ISignClient { Future requestWriteContract({ required String topic, required String chainId, - required String rpcUrl, required DeployedContract deployedContract, required String functionName, required Transaction transaction, diff --git a/lib/apis/sign_api/i_sign_engine_app.dart b/lib/apis/sign_api/i_sign_engine_app.dart index 05b1ffe8..ccfa481c 100644 --- a/lib/apis/sign_api/i_sign_engine_app.dart +++ b/lib/apis/sign_api/i_sign_engine_app.dart @@ -33,7 +33,6 @@ abstract class ISignEngineApp extends ISignEngineCommon { Future requestWriteContract({ required String topic, required String chainId, - required String rpcUrl, required DeployedContract deployedContract, required String functionName, required Transaction transaction, diff --git a/lib/apis/sign_api/sign_client.dart b/lib/apis/sign_api/sign_client.dart index fba5a520..4ddab595 100644 --- a/lib/apis/sign_api/sign_client.dart +++ b/lib/apis/sign_api/sign_client.dart @@ -293,7 +293,7 @@ class SignClient implements ISignClient { required String functionName, required String rpcUrl, EthereumAddress? sender, - List parameters = const [], + List parameters = const [], }) async { try { return await engine.requestReadContract( @@ -312,18 +312,16 @@ class SignClient implements ISignClient { 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 [], + String? method, }) async { try { return await engine.requestWriteContract( topic: topic, chainId: chainId, - rpcUrl: rpcUrl, deployedContract: deployedContract, functionName: functionName, transaction: transaction, diff --git a/lib/apis/sign_api/sign_engine.dart b/lib/apis/sign_api/sign_engine.dart index 5bbe1078..05a61f6a 100644 --- a/lib/apis/sign_api/sign_engine.dart +++ b/lib/apis/sign_api/sign_engine.dart @@ -6,7 +6,6 @@ import 'package:http/http.dart' as http; import 'package:walletconnect_flutter_v2/apis/core/pairing/utils/json_rpc_utils.dart'; import 'package:walletconnect_flutter_v2/apis/core/store/i_generic_store.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/i_sessions.dart'; -import 'package:walletconnect_flutter_v2/apis/sign_api/utils/custom_credentials.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/utils/sign_api_validator_utils.dart'; import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/utils/auth/recaps_utils.dart'; @@ -543,27 +542,20 @@ class SignEngine implements ISignEngine { 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 [], + String? method, }) async { if (transaction.from == null) { throw Exception('Transaction must include `from` value'); } - final credentials = CustomCredentials( - signEngine: this, - topic: topic, - chainId: chainId, - address: transaction.from!, - method: method, - ); + final trx = Transaction.callContract( contract: deployedContract, function: deployedContract.function(functionName), - from: credentials.address, + from: transaction.from!, value: transaction.value, maxGas: transaction.maxGas, gasPrice: transaction.gasPrice, @@ -573,13 +565,13 @@ class SignEngine implements ISignEngine { parameters: parameters, ); - if (chainId.contains(':')) { - chainId = chainId.split(':').last; - } - return await Web3Client(rpcUrl, http.Client()).sendTransaction( - credentials, - trx, - chainId: int.parse(chainId), + return await request( + topic: topic, + chainId: chainId, + request: SessionRequestParams( + method: method ?? MethodsConstants.ethSendTransaction, + params: [trx.toJson()], + ), ); } @@ -1869,11 +1861,10 @@ class SignEngine implements ISignEngine { ); final walletAddress = AddressUtils.getDidAddress(payload.iss); - final ethAddress = EthereumAddress.fromHex(walletAddress); final chainId = AddressUtils.getDidChainId(payload.iss); final isValid = await AuthSignature.verifySignature( - ethAddress.hexEip55, + walletAddress.toEIP55(), reconstructed, signature, chainId, @@ -1892,7 +1883,6 @@ class SignEngine implements ISignEngine { final header = '${cacaoPayload.domain} wants you to sign in with your Ethereum account:'; final walletAddress = AddressUtils.getDidAddress(iss); - final ethAddress = EthereumAddress.fromHex(walletAddress); if (cacaoPayload.aud.isEmpty) { throw WalletConnectError(code: -1, message: 'aud is required'); @@ -1929,7 +1919,7 @@ class SignEngine implements ISignEngine { final message = [ header, - ethAddress.hexEip55, + walletAddress.toEIP55(), '', statement, '', @@ -2390,7 +2380,7 @@ class SignEngine implements ISignEngine { final parsedAddress = AddressUtils.getDidAddress(payload.iss); for (var chain in approvedChains.toSet()) { - approvedAccounts.add('$chain:$parsedAddress'); + approvedAccounts.add('$chain:${parsedAddress.toEIP55()}'); } } } on WalletConnectError catch (e) { @@ -2589,7 +2579,7 @@ class SignEngine implements ISignEngine { final parsedAddress = AddressUtils.getDidAddress(payload.iss); for (var chain in approvedChains.toSet()) { - approvedAccounts.add('$chain:$parsedAddress'); + approvedAccounts.add('$chain:${parsedAddress.toEIP55()}'); } } diff --git a/lib/apis/sign_api/utils/auth/address_utils.dart b/lib/apis/sign_api/utils/auth/address_utils.dart index 77acd45e..ad6509e4 100644 --- a/lib/apis/sign_api/utils/auth/address_utils.dart +++ b/lib/apis/sign_api/utils/auth/address_utils.dart @@ -1,3 +1,5 @@ +import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart'; + class AddressUtils { static String getDidAddress(String iss) { return iss.split(':').last; @@ -11,3 +13,9 @@ class AddressUtils { return iss.substring(iss.indexOf(RegExp(r':')) + 1); } } + +extension AddressUtilsExtension on String { + String toEIP55() { + return EthereumAddress.fromHex(this).hexEip55; + } +} diff --git a/lib/apis/sign_api/utils/auth/auth_signature.dart b/lib/apis/sign_api/utils/auth/auth_signature.dart index bdd7ea50..826a105e 100644 --- a/lib/apis/sign_api/utils/auth/auth_signature.dart +++ b/lib/apis/sign_api/utils/auth/auth_signature.dart @@ -8,6 +8,7 @@ import 'package:walletconnect_flutter_v2/apis/core/pairing/utils/json_rpc_utils. import 'package:walletconnect_flutter_v2/apis/models/basic_models.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/models/auth/common_auth_models.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/models/auth/session_auth_models.dart'; +import 'package:walletconnect_flutter_v2/apis/sign_api/utils/auth/address_utils.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/utils/auth/auth_constants.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/utils/auth/recaps_utils.dart'; import 'package:web3dart/crypto.dart' as crypto; @@ -199,6 +200,8 @@ class AuthSignature { if (!iss.contains('did:pkh:')) { iss = 'did:pkh:$iss'; } + final address = AddressUtils.getDidAddress(iss); + iss = iss.replaceAll(address, address.toEIP55()); return Cacao( h: const CacaoHeader(t: CacaoHeader.CAIP122), p: CacaoPayload.fromRequestPayload( diff --git a/lib/apis/sign_api/utils/custom_credentials.dart b/lib/apis/sign_api/utils/custom_credentials.dart deleted file mode 100644 index 1db2c80e..00000000 --- a/lib/apis/sign_api/utils/custom_credentials.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'dart:convert'; -import 'dart:typed_data'; - -import 'package:walletconnect_flutter_v2/walletconnect_flutter_v2.dart'; -import 'package:web3dart/crypto.dart' as crypto; - -class CustomCredentials extends CustomTransactionSender { - CustomCredentials({ - required ISignEngine signEngine, - required String topic, - required String chainId, - required EthereumAddress address, - String? method, - }) : _signEngine = signEngine, - _topic = topic, - _chainId = chainId, - _address = address, - _method = method; - - final ISignEngine _signEngine; - final String _topic; - final String _chainId; - final EthereumAddress _address; - final String? _method; - - @override - EthereumAddress get address => _address; - - @override - Future sendTransaction(Transaction transaction) async { - final result = await _sendTransaction(transaction); - if (result is Map) { - return jsonEncode(result); - } - return result.toString(); - } - - Future _sendTransaction(Transaction transaction) async { - final sessionRequestParams = SessionRequestParams( - method: _method ?? MethodsConstants.ethSendTransaction, - params: [ - transaction.toJson(), - ], - ); - - final result = await _signEngine.request( - topic: _topic, - chainId: _chainId, - request: sessionRequestParams, - ); - return result; - } - - @override - Future extractAddress() => Future.value(_address); - - @override - Future signToSignature( - Uint8List payload, { - int? chainId, - bool isEIP1559 = false, - }) { - final signature = signToEcSignature( - payload, - chainId: chainId, - isEIP1559: isEIP1559, - ); - return Future.value(signature); - } - - @override - crypto.MsgSignature signToEcSignature( - Uint8List payload, { - int? chainId, - bool isEIP1559 = false, - }) { - // TODO: implement signToEcSignature - throw UnimplementedError(); - } -} diff --git a/lib/apis/utils/extensions.dart b/lib/apis/utils/extensions.dart index b9e04156..0d4c466c 100644 --- a/lib/apis/utils/extensions.dart +++ b/lib/apis/utils/extensions.dart @@ -7,8 +7,8 @@ import 'package:web3dart/crypto.dart' as crypto; extension TransactionExtension on Transaction { Map toJson() { return { - if (from != null) 'from': from!.hex, - if (to != null) 'to': to!.hex, + if (from != null) 'from': from!.hexEip55, + if (to != null) 'to': to!.hexEip55, if (maxGas != null) 'gas': '0x${maxGas!.toRadixString(16)}', if (gasPrice != null) 'gasPrice': '0x${gasPrice!.getInWei.toRadixString(16)}', diff --git a/lib/apis/web3app/web3app.dart b/lib/apis/web3app/web3app.dart index a0523310..a9bdd506 100644 --- a/lib/apis/web3app/web3app.dart +++ b/lib/apis/web3app/web3app.dart @@ -228,7 +228,7 @@ class Web3App implements IWeb3App { required String functionName, required String rpcUrl, EthereumAddress? sender, - List parameters = const [], + List parameters = const [], }) async { try { return await signEngine.requestReadContract( @@ -247,7 +247,6 @@ class Web3App implements IWeb3App { Future requestWriteContract({ required String topic, required String chainId, - required String rpcUrl, required DeployedContract deployedContract, required String functionName, required Transaction transaction, @@ -258,7 +257,6 @@ class Web3App implements IWeb3App { return await signEngine.requestWriteContract( topic: topic, chainId: chainId, - rpcUrl: rpcUrl, deployedContract: deployedContract, functionName: functionName, transaction: transaction, diff --git a/lib/src/version.dart b/lib/src/version.dart index d9d891dc..ea3a9755 100644 --- a/lib/src/version.dart +++ b/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '2.3.1-beta02'; +const packageVersion = '2.3.1'; diff --git a/pubspec.yaml b/pubspec.yaml index c5e7b410..71ac1658 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: walletconnect_flutter_v2 description: WalletConnect's official Dart library v2 for WalletKit and AppKit. The communications protocol for web3. -version: 2.3.1-beta02 +version: 2.3.1 repository: https://github.com/WalletConnect/WalletConnectFlutterV2 environment: diff --git a/test/core_api/pairing_test.dart b/test/core_api/pairing_test.dart index 25394894..1f0d5dad 100644 --- a/test/core_api/pairing_test.dart +++ b/test/core_api/pairing_test.dart @@ -267,18 +267,18 @@ void main() { }); test('clients can ping each other', () async { - final CreateResponse response = await coreA.pairing.create(); - // await coreB.pairing.pair(uri: response.uri); + // TODO more logs to check any fails in the future. + final pairingInfo = await coreA.pairing.create(); - Completer completer = Completer(); + final completer = Completer(); coreB.pairing.onPairingPing.subscribe((args) { expect(args != null, true); completer.complete(); }); + await coreB.pairing.pair(uri: pairingInfo.uri, activatePairing: true); - await coreB.pairing.pair(uri: response.uri, activatePairing: true); - await coreA.pairing.activate(topic: response.topic); - await coreA.pairing.ping(topic: response.topic); + await coreA.pairing.activate(topic: pairingInfo.topic); + await coreA.pairing.ping(topic: pairingInfo.topic); await completer.future; }); diff --git a/test/sign_api/utils/sign_client_test_wrapper.dart b/test/sign_api/utils/sign_client_test_wrapper.dart index cc8074ef..a83d5812 100644 --- a/test/sign_api/utils/sign_client_test_wrapper.dart +++ b/test/sign_api/utils/sign_client_test_wrapper.dart @@ -224,7 +224,7 @@ class SignClientTestWrapper implements ISignEngine { required String functionName, required String rpcUrl, EthereumAddress? sender, - List parameters = const [], + List parameters = const [], }) async { try { return await client.requestReadContract( @@ -243,18 +243,16 @@ class SignClientTestWrapper implements ISignEngine { 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 [], + List parameters = const [], }) async { try { return await client.requestWriteContract( topic: topic, chainId: chainId, - rpcUrl: rpcUrl, deployedContract: deployedContract, functionName: functionName, transaction: transaction,