import 'dart:async'; import 'package:flutter_breez_liquid/flutter_breez_liquid.dart' as liquid_sdk; import 'package:rxdart/rxdart.dart'; class BreezSDKLiquid { static final BreezSDKLiquid _singleton = BreezSDKLiquid._internal(); factory BreezSDKLiquid() => _singleton; BreezSDKLiquid._internal() { initializeLogStream(); } liquid_sdk.BindingLiquidSdk? _instance; liquid_sdk.BindingLiquidSdk? get instance => _instance; Future connect({ required liquid_sdk.ConnectRequest req, }) async { try { _instance = await liquid_sdk.connect(req: req); _initializeEventsStream(_instance!); _subscribeToSdkStreams(_instance!); await _fetchWalletData(_instance!); } catch (e) { _instance = null; rethrow; } } void disconnect() { if (_instance == null) { throw Exception(); } _instance!.disconnect(); _unsubscribeFromSdkStreams(); _instance = null; } Future _fetchWalletData(liquid_sdk.BindingLiquidSdk sdk) async { await _getInfo(sdk); await _listPayments(sdk: sdk); } Future _getInfo(liquid_sdk.BindingLiquidSdk sdk) async { final walletInfo = await sdk.getInfo(); _walletInfoController.add(walletInfo); return walletInfo; } Future> _listPayments({ required liquid_sdk.BindingLiquidSdk sdk, }) async { const req = liquid_sdk.ListPaymentsRequest(); final paymentsList = await sdk.listPayments(req: req); _paymentsController.add(paymentsList); return paymentsList; } StreamSubscription? _breezLogSubscription; Stream? _breezLogStream; /// Initializes SDK log stream. /// /// Call once on your Dart entrypoint file, e.g.; `lib/main.dart`. void initializeLogStream() { _breezLogStream ??= liquid_sdk.breezLogStream().asBroadcastStream(); } StreamSubscription? _breezEventsSubscription; Stream? _breezEventsStream; void _initializeEventsStream(liquid_sdk.BindingLiquidSdk sdk) { _breezEventsStream ??= sdk.addEventListener().asBroadcastStream(); } /// Subscribes to SDK's event & log streams. void _subscribeToSdkStreams(liquid_sdk.BindingLiquidSdk sdk) { _subscribeToEventsStream(sdk); _subscribeToLogStream(); } final StreamController _walletInfoController = BehaviorSubject(); Stream get walletInfoStream => _walletInfoController.stream; final StreamController _paymentResultStream = StreamController.broadcast(); final StreamController> _paymentsController = BehaviorSubject>(); Stream> get paymentsStream => _paymentsController.stream; Stream get paymentResultStream => _paymentResultStream.stream; /* TODO: Liquid - Log statements are added for debugging purposes, should be removed after early development stage is complete & events are behaving as expected.*/ /// Subscribes to SdkEvent's stream void _subscribeToEventsStream(liquid_sdk.BindingLiquidSdk sdk) { _breezEventsSubscription = _breezEventsStream?.listen( (event) async { if (event is liquid_sdk.SdkEvent_PaymentFailed) { _logStreamController.add( liquid_sdk.LogEntry(line: "Payment Failed. ${event.details.swapId}", level: "WARN"), ); _paymentResultStream.addError(PaymentException(event.details)); } if (event is liquid_sdk.SdkEvent_PaymentPending) { _logStreamController.add( liquid_sdk.LogEntry(line: "Payment Pending. ${event.details.swapId}", level: "INFO"), ); _paymentResultStream.add(event.details); } if (event is liquid_sdk.SdkEvent_PaymentRefunded) { _logStreamController.add( liquid_sdk.LogEntry(line: "Payment Refunded. ${event.details.swapId}", level: "INFO"), ); _paymentResultStream.add(event.details); } if (event is liquid_sdk.SdkEvent_PaymentRefundPending) { _logStreamController.add( liquid_sdk.LogEntry(line: "Pending Payment Refund. ${event.details.swapId}", level: "INFO"), ); _paymentResultStream.add(event.details); } if (event is liquid_sdk.SdkEvent_PaymentSucceeded) { _logStreamController.add( liquid_sdk.LogEntry(line: "Payment Succeeded. ${event.details.swapId}", level: "INFO"), ); _paymentResultStream.add(event.details); } if (event is liquid_sdk.SdkEvent_PaymentWaitingConfirmation) { _logStreamController.add( liquid_sdk.LogEntry(line: "Payment Waiting Confirmation. ${event.details.swapId}", level: "INFO"), ); _paymentResultStream.add(event.details); } if (event is liquid_sdk.SdkEvent_Synced) { _logStreamController.add(const liquid_sdk.LogEntry(line: "Received Synced event.", level: "INFO")); } await _fetchWalletData(sdk); }, ); } final _logStreamController = StreamController.broadcast(); Stream get logStream => _logStreamController.stream; /// Subscribes to SDK's logs stream void _subscribeToLogStream() { _breezLogSubscription = _breezLogStream?.listen((logEntry) { _logStreamController.add(logEntry); }, onError: (e) { _logStreamController.addError(e); }); } /// Unsubscribes from SDK's event & log streams. void _unsubscribeFromSdkStreams() { _breezEventsSubscription?.cancel(); _breezLogSubscription?.cancel(); } } // TODO: Liquid - Return this exception from the SDK directly class PaymentException { final liquid_sdk.Payment details; const PaymentException(this.details); }