diff --git a/CHANGELOG.md b/CHANGELOG.md index 006e9788..b1aba1a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -## 2.1.4 - UNRELEASED +## 2.1.5 + +- Added a core heartbeat to check and expire on pairing and sessions. + +## 2.1.4 - Core defaults to `Logger.level = Level.nothing` to prevent logs from being printed by default - Resolved errors with pairings and sessions trying to subscribe even when the relay wasn't connected diff --git a/example/dapp/lib/main.dart b/example/dapp/lib/main.dart index d1e47a99..d238b565 100644 --- a/example/dapp/lib/main.dart +++ b/example/dapp/lib/main.dart @@ -60,7 +60,7 @@ class _MyHomePageState extends State { Future initialize() async { // try { - print('Project ID: ${DartDefines.projectId}'); + debugPrint('Project ID: ${DartDefines.projectId}'); _web3App = await Web3App.createInstance( projectId: DartDefines.projectId, logLevel: LogLevel.info, diff --git a/example/dapp/lib/pages/connect_page.dart b/example/dapp/lib/pages/connect_page.dart index 8e14a9bd..9940b946 100644 --- a/example/dapp/lib/pages/connect_page.dart +++ b/example/dapp/lib/pages/connect_page.dart @@ -73,7 +73,12 @@ class ConnectPageState extends State { vertical: StyleConstants.linear8, ), child: ElevatedButton( - onPressed: () => _onConnect(_selectedChains), + onPressed: () => _onConnect( + _selectedChains, + showToast: (m) async { + await showPlatformToast(child: Text(m), context: context); + }, + ), style: ButtonStyle( backgroundColor: MaterialStateProperty.all( StyleConstants.primaryColor, @@ -155,9 +160,8 @@ class ConnectPageState extends State { ); } - Future _onConnect( - List chains, - ) async { + Future _onConnect(List chains, + {Function(String message)? showToast}) async { // Use the chain metadata to build the required namespaces: // Get the methods, get the events final Map requiredNamespaces = {}; @@ -192,12 +196,7 @@ class ConnectPageState extends State { final _ = await res.session.future; // print(sessionData); - showPlatformToast( - child: const Text( - StringConstants.connectionEstablished, - ), - context: context, - ); + showToast?.call(StringConstants.connectionEstablished); // Send off an auth request now that the pairing/session is established debugPrint('Requesting authentication'); @@ -216,19 +215,9 @@ class ConnectPageState extends State { if (authResponse.error != null) { debugPrint('Authentication failed: ${authResponse.error}'); - await showPlatformToast( - child: const Text( - StringConstants.authFailed, - ), - context: context, - ); + showToast?.call(StringConstants.authFailed); } else { - showPlatformToast( - child: const Text( - StringConstants.authSucceeded, - ), - context: context, - ); + showToast?.call(StringConstants.authSucceeded); } if (_shouldDismissQrCode) { @@ -241,12 +230,7 @@ class ConnectPageState extends State { // ignore: use_build_context_synchronously Navigator.pop(context); } - await showPlatformToast( - child: const Text( - StringConstants.connectionFailed, - ), - context: context, - ); + showToast?.call(StringConstants.connectionFailed); } } @@ -279,17 +263,18 @@ class ConnectPageState extends State { height: StyleConstants.linear16, ), ElevatedButton( - onPressed: () async { - await Clipboard.setData( + onPressed: () { + Clipboard.setData( ClipboardData( text: response.uri!.toString(), ), - ); - await showPlatformToast( - child: const Text( - StringConstants.copiedToClipboard, + ).then( + (_) => showPlatformToast( + child: const Text( + StringConstants.copiedToClipboard, + ), + context: context, ), - context: context, ); }, child: const Text( diff --git a/example/dapp/lib/widgets/method_dialog.dart b/example/dapp/lib/widgets/method_dialog.dart index a0bafed0..e745cf00 100644 --- a/example/dapp/lib/widgets/method_dialog.dart +++ b/example/dapp/lib/widgets/method_dialog.dart @@ -48,36 +48,25 @@ class MethodDialogState extends State { if (snapshot.hasData) { final String t = jsonEncode(snapshot.data); return InkWell( - onTap: () async { - await Clipboard.setData( - ClipboardData( - text: t, + onTap: () { + Clipboard.setData(ClipboardData(text: t)).then( + (_) => showPlatformToast( + child: const Text(StringConstants.copiedToClipboard), + context: context, ), ); - showPlatformToast( - child: const Text( - StringConstants.copiedToClipboard, - ), - context: context, - ); }, - child: Text( - t, - ), + child: Text(t), ); } else if (snapshot.hasError) { return InkWell( - onTap: () async { - await Clipboard.setData( - ClipboardData( - text: snapshot.data.toString(), - ), - ); - showPlatformToast( - child: const Text( - StringConstants.copiedToClipboard, + onTap: () { + Clipboard.setData(ClipboardData(text: snapshot.data.toString())) + .then( + (_) => showPlatformToast( + child: const Text(StringConstants.copiedToClipboard), + context: context, ), - context: context, ); }, child: Text( diff --git a/example/wallet/android/app/src/main/AndroidManifest.xml b/example/wallet/android/app/src/main/AndroidManifest.xml index 1e77c952..83cb3c1b 100644 --- a/example/wallet/android/app/src/main/AndroidManifest.xml +++ b/example/wallet/android/app/src/main/AndroidManifest.xml @@ -4,7 +4,7 @@ android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> onPulse.broadcast(), + ); + } + + @override + void stop() { + _heartbeatTimer?.cancel(); + _heartbeatTimer = null; + } + + @override + final Event onPulse = Event(); +} diff --git a/lib/apis/core/heartbit/i_heartbeat.dart b/lib/apis/core/heartbit/i_heartbeat.dart new file mode 100644 index 00000000..0f1a5ef0 --- /dev/null +++ b/lib/apis/core/heartbit/i_heartbeat.dart @@ -0,0 +1,9 @@ +import 'package:event/event.dart'; + +abstract class IHeartBeat { + abstract int interval; + abstract final Event onPulse; + + void init(); + void stop(); +} diff --git a/lib/apis/core/i_core.dart b/lib/apis/core/i_core.dart index 36c1e130..07bbac17 100644 --- a/lib/apis/core/i_core.dart +++ b/lib/apis/core/i_core.dart @@ -1,6 +1,7 @@ import 'package:logger/logger.dart'; import 'package:walletconnect_flutter_v2/apis/core/crypto/i_crypto.dart'; import 'package:walletconnect_flutter_v2/apis/core/echo/i_echo.dart'; +import 'package:walletconnect_flutter_v2/apis/core/heartbit/i_heartbeat.dart'; import 'package:walletconnect_flutter_v2/apis/core/pairing/i_expirer.dart'; import 'package:walletconnect_flutter_v2/apis/core/pairing/i_pairing.dart'; import 'package:walletconnect_flutter_v2/apis/core/relay_client/i_relay_client.dart'; @@ -14,11 +15,11 @@ abstract class ICore { abstract final String projectId; abstract final String pushUrl; - // abstract IHeartBeat heartbeat; + abstract IHeartBeat heartbeat; abstract ICrypto crypto; abstract IRelayClient relayClient; abstract IStore> storage; - // abstract IJsonRpcHistory history; + abstract IExpirer expirer; abstract IPairing pairing; abstract IEcho echo; diff --git a/lib/apis/core/pairing/i_pairing.dart b/lib/apis/core/pairing/i_pairing.dart index 650af137..ea0150a3 100644 --- a/lib/apis/core/pairing/i_pairing.dart +++ b/lib/apis/core/pairing/i_pairing.dart @@ -41,7 +41,9 @@ abstract class IPairing { required String topic, required PairingMetadata metadata, }); + Future checkAndExpire(); List getPairings(); + PairingInfo? getPairing({required String topic}); Future ping({required String topic}); Future disconnect({required String topic}); IPairingStore getStore(); diff --git a/lib/apis/core/pairing/pairing.dart b/lib/apis/core/pairing/pairing.dart index c9743649..9af04302 100644 --- a/lib/apis/core/pairing/pairing.dart +++ b/lib/apis/core/pairing/pairing.dart @@ -78,6 +78,7 @@ class Pairing implements IPairing { _registerRelayEvents(); _registerExpirerEvents(); + _registerheartbeatSubscription(); await core.expirer.init(); await pairings.init(); @@ -92,9 +93,14 @@ class Pairing implements IPairing { } @override - Future create({ - List>? methods, - }) async { + Future checkAndExpire() async { + for (var pairing in getPairings()) { + await core.expirer.checkAndExpire(pairing.topic); + } + } + + @override + Future create({List>? methods}) async { _checkInitialized(); final String symKey = core.crypto.getUtils().generateRandomBytes32(); final String topic = await core.crypto.setSymKey(symKey); @@ -310,6 +316,11 @@ class Pairing implements IPairing { return pairings.getAll(); } + @override + PairingInfo? getPairing({required String topic}) { + return pairings.get(topic); + } + @override Future ping({required String topic}) async { _checkInitialized(); @@ -385,7 +396,7 @@ class Pairing implements IPairing { int? ttl, EncodeOptions? encodeOptions, }) async { - core.logger.v( + core.logger.t( 'pairing sendResult, id: $id topic: $topic, method: $method, params: $params, ttl: $ttl', ); @@ -456,7 +467,7 @@ class Pairing implements IPairing { dynamic result, { EncodeOptions? encodeOptions, }) async { - core.logger.v( + core.logger.t( 'pairing sendResult, id: $id topic: $topic, method: $method, result: $result', ); final Map payload = @@ -491,7 +502,7 @@ class Pairing implements IPairing { JsonRpcError error, { EncodeOptions? encodeOptions, }) async { - core.logger.v( + core.logger.t( 'pairing sendError, id: $id topic: $topic, method: $method, error: $error', ); @@ -780,6 +791,10 @@ class Pairing implements IPairing { core.expirer.onExpire.subscribe(_onExpired); } + void _registerheartbeatSubscription() { + core.heartbeat.onPulse.subscribe(_heartbeatSubscription); + } + Future _onExpired(ExpirationEvent? event) async { if (event == null) { return; @@ -796,6 +811,11 @@ class Pairing implements IPairing { } } + void _heartbeatSubscription(EventArgs? args) async { + core.logger.i('Pairing heartbeat received'); + await checkAndExpire(); + } + /// ---- Validators ---- /// Future _isValidPing(String topic) async { diff --git a/lib/apis/core/relay_client/relay_client.dart b/lib/apis/core/relay_client/relay_client.dart index 0cdf221b..8ef1f2ac 100644 --- a/lib/apis/core/relay_client/relay_client.dart +++ b/lib/apis/core/relay_client/relay_client.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:event/event.dart'; -// import 'package:json_rpc_2/json_rpc_2.dart'; import 'package:walletconnect_flutter_v2/apis/core/i_core.dart'; import 'package:walletconnect_flutter_v2/apis/core/pairing/utils/json_rpc_utils.dart'; import 'package:walletconnect_flutter_v2/apis/core/relay_client/i_message_tracker.dart'; @@ -75,15 +74,13 @@ class RelayClient implements IRelayClient { ICore core; - Timer? _heartbeatTimer; - final int heartbeatPeriod; + bool _subscribedToHeartbeat = false; RelayClient({ required this.core, required this.messageTracker, required this.topicMap, IWebSocketHandler? socketHandler, - this.heartbeatPeriod = 5, }) : socketHandler = socketHandler ?? WebSocketHandler(); @override @@ -97,9 +94,7 @@ class RelayClient implements IRelayClient { // Setup the json RPC server await _connect(); - // _connectingFuture = _createJsonRPCProvider(); - // await _connectingFuture; - // _startHeartbeat(); + _subscribeToHeartbeat(); _initialized = true; } @@ -190,7 +185,7 @@ class RelayClient implements IRelayClient { /// PRIVATE FUNCTIONS /// Future _connect({String? relayUrl}) async { - core.logger.v('RelayClient Internal: Connecting to relay'); + core.logger.t('RelayClient Internal: Connecting to relay'); if (isConnected) { return; } @@ -203,9 +198,7 @@ class RelayClient implements IRelayClient { // Connect and track the connection progress, then start the heartbeat _connectingFuture = _createJsonRPCProvider(); await _connectingFuture; - if (_heartbeatTimer == null) { - _startHeartbeat(); - } + _subscribeToHeartbeat(); // If it didn't connect, and the relayUrl is the default, // recursively try the fallback @@ -223,7 +216,7 @@ class RelayClient implements IRelayClient { } Future _disconnect() async { - core.logger.v('RelayClient Internal: Disconnecting from relay'); + core.logger.t('RelayClient Internal: Disconnecting from relay'); _active = false; final bool shouldBroadcastDisonnect = isConnected; @@ -231,8 +224,7 @@ class RelayClient implements IRelayClient { await jsonRPC?.close(); jsonRPC = null; await socketHandler.close(); - _heartbeatTimer?.cancel(); - _heartbeatTimer = null; + _unsubscribeToHeartbeat(); if (shouldBroadcastDisonnect) { onRelayClientDisconnect.broadcast(); @@ -243,7 +235,7 @@ class RelayClient implements IRelayClient { _connecting = true; _active = true; var auth = await core.crypto.signJWT(core.relayUrl); - core.logger.v('Signed JWT: $auth'); + core.logger.t('Signed JWT: $auth'); try { final String url = WalletConnectUtils.formatRelayRpcUrl( protocol: WalletConnectConstants.CORE_PROTOCOL, @@ -259,7 +251,7 @@ class RelayClient implements IRelayClient { jsonRPC = null; } - core.logger.v('Initializing WebSocket with $url'); + core.logger.t('Initializing WebSocket with $url'); await socketHandler.setup( url: url, ); @@ -351,16 +343,24 @@ class RelayClient implements IRelayClient { } } - void _startHeartbeat() { - _heartbeatTimer = Timer.periodic( - Duration(seconds: heartbeatPeriod), - (timer) async { - if (jsonRPC != null && jsonRPC!.isClosed) { - core.logger.v('Heartbeat, WebSocket closed, reconnecting'); - await connect(); - } - }, - ); + void _subscribeToHeartbeat() { + if (!_subscribedToHeartbeat) { + core.heartbeat.onPulse.subscribe(_heartbeatSubscription); + _subscribedToHeartbeat = true; + } + } + + void _unsubscribeToHeartbeat() { + core.heartbeat.onPulse.unsubscribe(_heartbeatSubscription); + _subscribedToHeartbeat = false; + } + + void _heartbeatSubscription(EventArgs? args) async { + core.logger.i('RelayClient heartbeat received'); + if (jsonRPC != null && jsonRPC!.isClosed) { + core.logger.t('RelayClient, WebSocket closed, reconnecting'); + await connect(); + } } String _buildMethod(String method) { @@ -370,7 +370,7 @@ class RelayClient implements IRelayClient { /// JSON RPC MESSAGE HANDLERS Future handlePublish(String topic, String message) async { - core.logger.v('Handling Publish Message: $topic, $message'); + core.logger.t('Handling Publish Message: $topic, $message'); // If we want to ignore the message, stop if (await _shouldIgnoreMessageEvent(topic, message)) { core.logger.w('Ignoring Message: $topic, $message'); diff --git a/lib/apis/sign_api/i_sign_engine.dart b/lib/apis/sign_api/i_sign_engine.dart index e11d8654..39daf336 100644 --- a/lib/apis/sign_api/i_sign_engine.dart +++ b/lib/apis/sign_api/i_sign_engine.dart @@ -1,4 +1,6 @@ import 'package:walletconnect_flutter_v2/apis/sign_api/i_sign_engine_app.dart'; import 'package:walletconnect_flutter_v2/apis/sign_api/i_sign_engine_wallet.dart'; -abstract class ISignEngine implements ISignEngineWallet, ISignEngineApp {} +abstract class ISignEngine implements ISignEngineWallet, ISignEngineApp { + Future checkAndExpire(); +} diff --git a/lib/apis/sign_api/sign_engine.dart b/lib/apis/sign_api/sign_engine.dart index 93e54f44..ac3117e1 100644 --- a/lib/apis/sign_api/sign_engine.dart +++ b/lib/apis/sign_api/sign_engine.dart @@ -103,6 +103,13 @@ class SignEngine implements ISignEngine { _initialized = true; } + @override + Future checkAndExpire() async { + for (var session in sessions.getAll()) { + await core.expirer.checkAndExpire(session.topic); + } + } + @override Future connect({ Map? requiredNamespaces, @@ -566,25 +573,33 @@ class SignEngine implements ISignEngine { required WalletConnectError reason, }) async { _checkInitialized(); - await _isValidDisconnect(topic); + try { + await _isValidDisconnect(topic); - if (sessions.has(topic)) { - // Send the request to delete the session, we don't care if it fails - try { - core.pairing.sendRequest( - topic, - MethodConstants.WC_SESSION_DELETE, - WcSessionDeleteRequest( - code: reason.code, - message: reason.message, - data: reason.data, - ), - ); - } catch (_) {} + if (sessions.has(topic)) { + // Send the request to delete the session, we don't care if it fails + try { + core.pairing.sendRequest( + topic, + MethodConstants.WC_SESSION_DELETE, + WcSessionDeleteRequest( + code: reason.code, + message: reason.message, + data: reason.data, + ), + ); + } catch (_) {} - await _deleteSession(topic); - } else { - await core.pairing.disconnect(topic: topic); + await _deleteSession(topic); + } else { + await core.pairing.disconnect(topic: topic); + } + } on WalletConnectError catch (error, s) { + core.logger.e( + '[$runtimeType] disconnectSession()', + error: error, + stackTrace: s, + ); } } @@ -874,7 +889,7 @@ class SignEngine implements ISignEngine { JsonRpcRequest payload, ) async { try { - core.logger.v( + core.logger.t( '_onSessionProposeRequest, topic: $topic, payload: $payload', ); final proposeRequest = WcSessionProposeRequest.fromJson(payload.params); @@ -906,7 +921,7 @@ class SignEngine implements ISignEngine { ); } on WalletConnectError catch (err) { // If they aren't, send an error - core.logger.v( + core.logger.t( '_onSessionProposeRequest WalletConnectError: $err', ); await core.pairing.sendError( @@ -1003,7 +1018,10 @@ class SignEngine implements ISignEngine { topic: sProposalCompleter.pairingTopic, metadata: request.controller.metadata, ); - await core.pairing.activate(topic: topic); + final pairing = core.pairing.getPairing(topic: topic); + if (pairing != null && !pairing.active) { + await core.pairing.activate(topic: topic); + } // Send the session back to the completer sProposalCompleter.completer.complete(session); @@ -1347,6 +1365,7 @@ class SignEngine implements ISignEngine { core.expirer.onExpire.subscribe(_onExpired); core.pairing.onPairingDelete.subscribe(_onPairingDelete); core.pairing.onPairingExpire.subscribe(_onPairingDelete); + core.heartbeat.onPulse.subscribe(_heartbeatSubscription); } Future _onRelayConnect(EventArgs? args) async { @@ -1421,6 +1440,11 @@ class SignEngine implements ISignEngine { } } + void _heartbeatSubscription(EventArgs? args) async { + core.logger.i('SignEngine heartbeat received'); + await checkAndExpire(); + } + /// ---- Validation Helpers ---- /// Future _isValidSessionTopic(String topic) async { @@ -1673,9 +1697,7 @@ class SignEngine implements ISignEngine { return true; } - Future _isValidDisconnect( - String topic, - ) async { + Future _isValidDisconnect(String topic) async { await _isValidSessionOrPairingTopic(topic); return true; diff --git a/lib/apis/utils/constants.dart b/lib/apis/utils/constants.dart index 6f737234..3c09d31d 100644 --- a/lib/apis/utils/constants.dart +++ b/lib/apis/utils/constants.dart @@ -1,5 +1,5 @@ class WalletConnectConstants { - static const SDK_VERSION = '2.1.4'; + static const SDK_VERSION = '2.1.5'; static const CORE_PROTOCOL = 'wc'; static const CORE_VERSION = 2; diff --git a/lib/apis/utils/log_level.dart b/lib/apis/utils/log_level.dart index 617c83be..9be00760 100644 --- a/lib/apis/utils/log_level.dart +++ b/lib/apis/utils/log_level.dart @@ -12,7 +12,7 @@ enum LogLevel { Level toLevel() { switch (this) { case LogLevel.verbose: - return Level.verbose; + return Level.trace; case LogLevel.debug: return Level.debug; case LogLevel.info: @@ -22,9 +22,9 @@ enum LogLevel { case LogLevel.error: return Level.error; case LogLevel.wtf: - return Level.wtf; + return Level.fatal; default: - return Level.nothing; + return Level.off; } } } diff --git a/lib/apis/utils/walletconnect_utils.dart b/lib/apis/utils/walletconnect_utils.dart index 0365cbcf..60b2abe3 100644 --- a/lib/apis/utils/walletconnect_utils.dart +++ b/lib/apis/utils/walletconnect_utils.dart @@ -16,6 +16,11 @@ class WalletConnectUtils { 0; } + static DateTime expiryToDateTime(int expiry) { + final milliseconds = expiry * 1000; + return DateTime.fromMillisecondsSinceEpoch(milliseconds); + } + static int toMilliseconds(int seconds) { return seconds * 1000; } diff --git a/lib/src/version.dart b/lib/src/version.dart index 6a6a1c1e..a0aa4231 100644 --- a/lib/src/version.dart +++ b/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '2.1.4'; +const packageVersion = '2.1.5'; diff --git a/pubspec.yaml b/pubspec.yaml index 06507bf8..306dcd90 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: walletconnect_flutter_v2 -description: WalletConnect v2 client made in dart for flutter. -version: 2.1.4 +description: This repository contains oficial implementation of WalletConnect v2 protocols for Flutter applications. The communications protocol for web3. +version: 2.1.5 repository: https://github.com/WalletConnect/WalletConnectFlutterV2 environment: @@ -25,7 +25,7 @@ dependencies: universal_io: ^2.0.4 stack_trace: ^1.10.0 web3dart: ^2.5.1 - logger: ^1.4.0 + logger: ^2.0.2+1 freezed_annotation: ^2.2.0 dev_dependencies: diff --git a/test/shared/shared_test_utils.mocks.dart b/test/shared/shared_test_utils.mocks.dart index 40a73915..b1851704 100644 --- a/test/shared/shared_test_utils.mocks.dart +++ b/test/shared/shared_test_utils.mocks.dart @@ -3,24 +3,26 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i18; -import 'dart:typed_data' as _i17; +import 'dart:async' as _i19; +import 'dart:typed_data' as _i18; import 'package:event/event.dart' as _i8; import 'package:http/http.dart' as _i9; -import 'package:logger/logger.dart' as _i15; +import 'package:logger/logger.dart' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:walletconnect_flutter_v2/apis/core/core.dart' as _i23; -import 'package:walletconnect_flutter_v2/apis/core/crypto/crypto.dart' as _i19; +import 'package:walletconnect_flutter_v2/apis/core/core.dart' as _i24; +import 'package:walletconnect_flutter_v2/apis/core/crypto/crypto.dart' as _i20; import 'package:walletconnect_flutter_v2/apis/core/crypto/crypto_models.dart' as _i2; import 'package:walletconnect_flutter_v2/apis/core/crypto/crypto_utils.dart' - as _i16; + as _i17; import 'package:walletconnect_flutter_v2/apis/core/crypto/i_crypto.dart' as _i10; import 'package:walletconnect_flutter_v2/apis/core/crypto/i_crypto_utils.dart' as _i5; import 'package:walletconnect_flutter_v2/apis/core/echo/i_echo.dart' as _i14; +import 'package:walletconnect_flutter_v2/apis/core/heartbit/i_heartbeat.dart' + as _i15; import 'package:walletconnect_flutter_v2/apis/core/i_core.dart' as _i3; import 'package:walletconnect_flutter_v2/apis/core/pairing/i_expirer.dart' as _i12; @@ -31,16 +33,16 @@ import 'package:walletconnect_flutter_v2/apis/core/relay_auth/i_relay_auth.dart' import 'package:walletconnect_flutter_v2/apis/core/relay_client/i_relay_client.dart' as _i11; import 'package:walletconnect_flutter_v2/apis/core/relay_client/message_tracker.dart' - as _i20; + as _i21; import 'package:walletconnect_flutter_v2/apis/core/relay_client/websocket/http_client.dart' - as _i22; + as _i23; import 'package:walletconnect_flutter_v2/apis/core/relay_client/websocket/websocket_handler.dart' - as _i24; + as _i25; import 'package:walletconnect_flutter_v2/apis/core/store/i_generic_store.dart' as _i4; import 'package:walletconnect_flutter_v2/apis/core/store/i_store.dart' as _i7; import 'package:walletconnect_flutter_v2/apis/core/store/store_models.dart' - as _i21; + as _i22; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -207,8 +209,18 @@ class _FakeIEcho_14 extends _i1.SmartFake implements _i14.IEcho { ); } -class _FakeLogger_15 extends _i1.SmartFake implements _i15.Logger { - _FakeLogger_15( +class _FakeIHeartBeat_15 extends _i1.SmartFake implements _i15.IHeartBeat { + _FakeIHeartBeat_15( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeLogger_16 extends _i1.SmartFake implements _i16.Logger { + _FakeLogger_16( Object parent, Invocation parentInvocation, ) : super( @@ -220,7 +232,7 @@ class _FakeLogger_15 extends _i1.SmartFake implements _i15.Logger { /// A class which mocks [CryptoUtils]. /// /// See the documentation for Mockito's code generation for more information. -class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { +class MockCryptoUtils extends _i1.Mock implements _i17.CryptoUtils { MockCryptoUtils() { _i1.throwOnMissingStub(this); } @@ -240,13 +252,13 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { ), ) as _i2.CryptoKeyPair); @override - _i17.Uint8List randomBytes(int? length) => (super.noSuchMethod( + _i18.Uint8List randomBytes(int? length) => (super.noSuchMethod( Invocation.method( #randomBytes, [length], ), - returnValue: _i17.Uint8List(0), - ) as _i17.Uint8List); + returnValue: _i18.Uint8List(0), + ) as _i18.Uint8List); @override String generateRandomBytes32() => (super.noSuchMethod( Invocation.method( @@ -256,7 +268,7 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { returnValue: '', ) as String); @override - _i18.Future deriveSymKey( + _i19.Future deriveSymKey( String? privKeyA, String? pubKeyB, ) => @@ -268,8 +280,8 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { pubKeyB, ], ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override String hashKey(String? key) => (super.noSuchMethod( Invocation.method( @@ -287,7 +299,7 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { returnValue: '', ) as String); @override - _i18.Future encrypt( + _i19.Future encrypt( String? message, String? symKey, { int? type, @@ -307,10 +319,10 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { #senderPublicKey: senderPublicKey, }, ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override - _i18.Future decrypt( + _i19.Future decrypt( String? symKey, String? encoded, ) => @@ -322,14 +334,14 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { encoded, ], ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override String serialize( int? type, - _i17.Uint8List? sealed, - _i17.Uint8List? iv, { - _i17.Uint8List? senderPublicKey, + _i18.Uint8List? sealed, + _i18.Uint8List? iv, { + _i18.Uint8List? senderPublicKey, }) => (super.noSuchMethod( Invocation.method( @@ -419,7 +431,7 @@ class MockCryptoUtils extends _i1.Mock implements _i16.CryptoUtils { /// A class which mocks [Crypto]. /// /// See the documentation for Mockito's code generation for more information. -class MockCrypto extends _i1.Mock implements _i19.Crypto { +class MockCrypto extends _i1.Mock implements _i20.Crypto { MockCrypto() { _i1.throwOnMissingStub(this); } @@ -486,14 +498,14 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { returnValue: '', ) as String); @override - _i18.Future init() => (super.noSuchMethod( + _i19.Future init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override bool hasKeys(String? tag) => (super.noSuchMethod( Invocation.method( @@ -503,23 +515,23 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { returnValue: false, ) as bool); @override - _i18.Future getClientId() => (super.noSuchMethod( + _i19.Future getClientId() => (super.noSuchMethod( Invocation.method( #getClientId, [], ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override - _i18.Future generateKeyPair() => (super.noSuchMethod( + _i19.Future generateKeyPair() => (super.noSuchMethod( Invocation.method( #generateKeyPair, [], ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override - _i18.Future generateSharedKey( + _i19.Future generateSharedKey( String? selfPublicKey, String? peerPublicKey, { String? overrideTopic, @@ -533,10 +545,10 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { ], {#overrideTopic: overrideTopic}, ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override - _i18.Future setSymKey( + _i19.Future setSymKey( String? symKey, { String? overrideTopic, }) => @@ -546,28 +558,28 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { [symKey], {#overrideTopic: overrideTopic}, ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override - _i18.Future deleteKeyPair(String? publicKey) => (super.noSuchMethod( + _i19.Future deleteKeyPair(String? publicKey) => (super.noSuchMethod( Invocation.method( #deleteKeyPair, [publicKey], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future deleteSymKey(String? topic) => (super.noSuchMethod( + _i19.Future deleteSymKey(String? topic) => (super.noSuchMethod( Invocation.method( #deleteSymKey, [topic], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future encode( + _i19.Future encode( String? topic, Map? payload, { _i2.EncodeOptions? options, @@ -581,10 +593,10 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { ], {#options: options}, ), - returnValue: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future decode( + _i19.Future decode( String? topic, String? encoded, { _i2.DecodeOptions? options, @@ -598,16 +610,16 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { ], {#options: options}, ), - returnValue: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future signJWT(String? aud) => (super.noSuchMethod( + _i19.Future signJWT(String? aud) => (super.noSuchMethod( Invocation.method( #signJWT, [aud], ), - returnValue: _i18.Future.value(''), - ) as _i18.Future); + returnValue: _i19.Future.value(''), + ) as _i19.Future); @override int getPayloadType(String? encoded) => (super.noSuchMethod( Invocation.method( @@ -635,7 +647,7 @@ class MockCrypto extends _i1.Mock implements _i19.Crypto { /// A class which mocks [MessageTracker]. /// /// See the documentation for Mockito's code generation for more information. -class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { +class MockMessageTracker extends _i1.Mock implements _i21.MessageTracker { MockMessageTracker() { _i1.throwOnMissingStub(this); } @@ -659,40 +671,40 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { ), ) as _i7.IStore); @override - _i8.Event<_i21.StoreCreateEvent>> get onCreate => + _i8.Event<_i22.StoreCreateEvent>> get onCreate => (super.noSuchMethod( Invocation.getter(#onCreate), - returnValue: _FakeEvent_8<_i21.StoreCreateEvent>>( + returnValue: _FakeEvent_8<_i22.StoreCreateEvent>>( this, Invocation.getter(#onCreate), ), - ) as _i8.Event<_i21.StoreCreateEvent>>); + ) as _i8.Event<_i22.StoreCreateEvent>>); @override - _i8.Event<_i21.StoreUpdateEvent>> get onUpdate => + _i8.Event<_i22.StoreUpdateEvent>> get onUpdate => (super.noSuchMethod( Invocation.getter(#onUpdate), - returnValue: _FakeEvent_8<_i21.StoreUpdateEvent>>( + returnValue: _FakeEvent_8<_i22.StoreUpdateEvent>>( this, Invocation.getter(#onUpdate), ), - ) as _i8.Event<_i21.StoreUpdateEvent>>); + ) as _i8.Event<_i22.StoreUpdateEvent>>); @override - _i8.Event<_i21.StoreDeleteEvent>> get onDelete => + _i8.Event<_i22.StoreDeleteEvent>> get onDelete => (super.noSuchMethod( Invocation.getter(#onDelete), - returnValue: _FakeEvent_8<_i21.StoreDeleteEvent>>( + returnValue: _FakeEvent_8<_i22.StoreDeleteEvent>>( this, Invocation.getter(#onDelete), ), - ) as _i8.Event<_i21.StoreDeleteEvent>>); + ) as _i8.Event<_i22.StoreDeleteEvent>>); @override - _i8.Event<_i21.StoreSyncEvent> get onSync => (super.noSuchMethod( + _i8.Event<_i22.StoreSyncEvent> get onSync => (super.noSuchMethod( Invocation.getter(#onSync), - returnValue: _FakeEvent_8<_i21.StoreSyncEvent>( + returnValue: _FakeEvent_8<_i22.StoreSyncEvent>( this, Invocation.getter(#onSync), ), - ) as _i8.Event<_i21.StoreSyncEvent>); + ) as _i8.Event<_i22.StoreSyncEvent>); @override Map> get data => (super.noSuchMethod( Invocation.getter(#data), @@ -725,7 +737,7 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { returnValue: '', ) as String); @override - _i18.Future recordMessageEvent( + _i19.Future recordMessageEvent( String? topic, String? message, ) => @@ -737,9 +749,9 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { message, ], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override bool messageIsRecorded( String? topic, @@ -756,14 +768,14 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { returnValue: false, ) as bool); @override - _i18.Future init() => (super.noSuchMethod( + _i19.Future init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override bool has(String? key) => (super.noSuchMethod( Invocation.method( @@ -787,7 +799,7 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { returnValue: >[], ) as List>); @override - _i18.Future set( + _i19.Future set( String? key, Map? value, ) => @@ -799,36 +811,36 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { value, ], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future delete(String? key) => (super.noSuchMethod( + _i19.Future delete(String? key) => (super.noSuchMethod( Invocation.method( #delete, [key], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future persist() => (super.noSuchMethod( + _i19.Future persist() => (super.noSuchMethod( Invocation.method( #persist, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future restore() => (super.noSuchMethod( + _i19.Future restore() => (super.noSuchMethod( Invocation.method( #restore, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override void checkInitialized() => super.noSuchMethod( Invocation.method( @@ -842,13 +854,13 @@ class MockMessageTracker extends _i1.Mock implements _i20.MessageTracker { /// A class which mocks [HttpWrapper]. /// /// See the documentation for Mockito's code generation for more information. -class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { +class MockHttpWrapper extends _i1.Mock implements _i23.HttpWrapper { MockHttpWrapper() { _i1.throwOnMissingStub(this); } @override - _i18.Future<_i9.Response> get( + _i19.Future<_i9.Response> get( Uri? url, { Map? headers, }) => @@ -858,7 +870,7 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { [url], {#headers: headers}, ), - returnValue: _i18.Future<_i9.Response>.value(_FakeResponse_9( + returnValue: _i19.Future<_i9.Response>.value(_FakeResponse_9( this, Invocation.method( #get, @@ -866,9 +878,9 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { {#headers: headers}, ), )), - ) as _i18.Future<_i9.Response>); + ) as _i19.Future<_i9.Response>); @override - _i18.Future<_i9.Response> delete( + _i19.Future<_i9.Response> delete( Uri? url, { Map? headers, }) => @@ -878,7 +890,7 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { [url], {#headers: headers}, ), - returnValue: _i18.Future<_i9.Response>.value(_FakeResponse_9( + returnValue: _i19.Future<_i9.Response>.value(_FakeResponse_9( this, Invocation.method( #delete, @@ -886,9 +898,9 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { {#headers: headers}, ), )), - ) as _i18.Future<_i9.Response>); + ) as _i19.Future<_i9.Response>); @override - _i18.Future<_i9.Response> post( + _i19.Future<_i9.Response> post( Uri? url, { Map? headers, Object? body, @@ -902,7 +914,7 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { #body: body, }, ), - returnValue: _i18.Future<_i9.Response>.value(_FakeResponse_9( + returnValue: _i19.Future<_i9.Response>.value(_FakeResponse_9( this, Invocation.method( #post, @@ -913,13 +925,13 @@ class MockHttpWrapper extends _i1.Mock implements _i22.HttpWrapper { }, ), )), - ) as _i18.Future<_i9.Response>); + ) as _i19.Future<_i9.Response>); } /// A class which mocks [Core]. /// /// See the documentation for Mockito's code generation for more information. -class MockCore extends _i1.Mock implements _i23.Core { +class MockCore extends _i1.Mock implements _i24.Core { MockCore() { _i1.throwOnMissingStub(this); } @@ -1028,6 +1040,22 @@ class MockCore extends _i1.Mock implements _i23.Core { returnValueForMissingStub: null, ); @override + _i15.IHeartBeat get heartbeat => (super.noSuchMethod( + Invocation.getter(#heartbeat), + returnValue: _FakeIHeartBeat_15( + this, + Invocation.getter(#heartbeat), + ), + ) as _i15.IHeartBeat); + @override + set heartbeat(_i15.IHeartBeat? _heartbeat) => super.noSuchMethod( + Invocation.setter( + #heartbeat, + _heartbeat, + ), + returnValueForMissingStub: null, + ); + @override _i7.IStore> get storage => (super.noSuchMethod( Invocation.getter(#storage), returnValue: _FakeIStore_7>( @@ -1054,63 +1082,63 @@ class MockCore extends _i1.Mock implements _i23.Core { returnValue: '', ) as String); @override - _i15.Logger get logger => (super.noSuchMethod( + _i16.Logger get logger => (super.noSuchMethod( Invocation.getter(#logger), - returnValue: _FakeLogger_15( + returnValue: _FakeLogger_16( this, Invocation.getter(#logger), ), - ) as _i15.Logger); + ) as _i16.Logger); @override - _i18.Future start() => (super.noSuchMethod( + _i19.Future start() => (super.noSuchMethod( Invocation.method( #start, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); } /// A class which mocks [WebSocketHandler]. /// /// See the documentation for Mockito's code generation for more information. -class MockWebSocketHandler extends _i1.Mock implements _i24.WebSocketHandler { +class MockWebSocketHandler extends _i1.Mock implements _i25.WebSocketHandler { MockWebSocketHandler() { _i1.throwOnMissingStub(this); } @override - _i18.Future get ready => (super.noSuchMethod( + _i19.Future get ready => (super.noSuchMethod( Invocation.getter(#ready), - returnValue: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future setup({required String? url}) => (super.noSuchMethod( + _i19.Future setup({required String? url}) => (super.noSuchMethod( Invocation.method( #setup, [], {#url: url}, ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future connect() => (super.noSuchMethod( + _i19.Future connect() => (super.noSuchMethod( Invocation.method( #connect, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); @override - _i18.Future close() => (super.noSuchMethod( + _i19.Future close() => (super.noSuchMethod( Invocation.method( #close, [], ), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) as _i18.Future); + returnValue: _i19.Future.value(), + returnValueForMissingStub: _i19.Future.value(), + ) as _i19.Future); } diff --git a/test/sign_api/utils/sign_client_test_wrapper.dart b/test/sign_api/utils/sign_client_test_wrapper.dart index 89bd5737..6830fde0 100644 --- a/test/sign_api/utils/sign_client_test_wrapper.dart +++ b/test/sign_api/utils/sign_client_test_wrapper.dart @@ -52,7 +52,7 @@ class SignClientTestWrapper implements ISignEngine { String relayUrl = WalletConnectConstants.DEFAULT_RELAY_URL, required PairingMetadata metadata, bool memoryStore = false, - Level logLevel = Level.nothing, + Level logLevel = Level.off, IHttpClient httpClient = const HttpWrapper(), }) async { final client = SignClientTestWrapper( @@ -377,4 +377,11 @@ class SignClientTestWrapper implements ISignEngine { @override IPairingStore get pairings => core.pairing.getStore(); + + @override + Future checkAndExpire() async { + for (var session in sessions.getAll()) { + await core.expirer.checkAndExpire(session.topic); + } + } }