Skip to content

Commit

Permalink
Support pasting LNURL #591
Browse files Browse the repository at this point in the history
- Update breez_translations for unsupported input's error message
- Expose parseInput api through InputBloc
- Remove utils/lnurl.dart
  • Loading branch information
erdemyerebasmaz committed Jul 5, 2023
1 parent 8c5fb82 commit 3b32393
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 145 deletions.
54 changes: 27 additions & 27 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,39 @@ PODS:
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
- Firebase/CoreOnly (10.9.0):
- FirebaseCore (= 10.9.0)
- Firebase/DynamicLinks (10.9.0):
- Firebase/CoreOnly (10.10.0):
- FirebaseCore (= 10.10.0)
- Firebase/DynamicLinks (10.10.0):
- Firebase/CoreOnly
- FirebaseDynamicLinks (~> 10.9.0)
- Firebase/Messaging (10.9.0):
- FirebaseDynamicLinks (~> 10.10.0)
- Firebase/Messaging (10.10.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 10.9.0)
- firebase_core (2.13.1):
- Firebase/CoreOnly (= 10.9.0)
- FirebaseMessaging (~> 10.10.0)
- firebase_core (2.14.0):
- Firebase/CoreOnly (= 10.10.0)
- Flutter
- firebase_dynamic_links (5.3.2):
- Firebase/DynamicLinks (= 10.9.0)
- firebase_dynamic_links (5.3.3):
- Firebase/DynamicLinks (= 10.10.0)
- firebase_core
- Flutter
- firebase_messaging (14.6.2):
- Firebase/Messaging (= 10.9.0)
- firebase_messaging (14.6.4):
- Firebase/Messaging (= 10.10.0)
- firebase_core
- Flutter
- FirebaseCore (10.9.0):
- FirebaseCore (10.10.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.10.0):
- FirebaseCoreInternal (10.11.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseDynamicLinks (10.9.0):
- FirebaseDynamicLinks (10.10.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (10.10.0):
- FirebaseInstallations (10.11.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
- PromisesObjC (~> 2.1)
- FirebaseMessaging (10.9.0):
- FirebaseMessaging (10.10.0):
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleDataTransport (~> 9.2)
Expand Down Expand Up @@ -283,15 +283,15 @@ SPEC CHECKSUMS:
breez_sdk: b771ec4372e4a757a05778e50c65a3da0dff101a
clipboard_watcher: 86fb70421aca6f4944e0591a8292605da7784666
connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a
Firebase: bd152f0f3d278c4060c5c71359db08ebcfd5a3e2
firebase_core: ce64b0941c6d87c6ef5022ae9116a158236c8c94
firebase_dynamic_links: db9f2ebcc3ea646e76a1d3ee37e9e57890ff0a83
firebase_messaging: 42912365e62efc1ea3e00724e5eecba6068ddb88
FirebaseCore: b68d3616526ec02e4d155166bbafb8eca64af557
FirebaseCoreInternal: 971029061d326000d65bfdc21f5502c75c8b0893
FirebaseDynamicLinks: 8cb66c4f403aa6ddf86ff3bc3c383a652f344ce9
FirebaseInstallations: 52153982b057d3afcb4e1fbb3eb0b6d00611e681
FirebaseMessaging: 6b7052cc3da7bc8e5f72bef871243e8f04a14eed
Firebase: facd334e557a979bd03a0b58d90fd56b52b8aba0
firebase_core: 85b6664038311940ad60584eaabc73103c61f5de
firebase_dynamic_links: 8e1ef5000616eb1004f06ec5cdd5e679ef199c29
firebase_messaging: c55f70dd48a998dea00a29ccf94572e1e4d454b2
FirebaseCore: d027ff503d37edb78db98429b11f580a24a7df2a
FirebaseCoreInternal: 9e46c82a14a3b3a25be4e1e151ce6d21536b89c0
FirebaseDynamicLinks: 3f61f496236d30fa749377159fb7b3d82ecb3c49
FirebaseInstallations: 2a2c6859354cbec0a228a863d4daf6de7c74ced4
FirebaseMessaging: 8a3b9a8b98ce72a42d22e69865cf662e38d2d6f5
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_fgbg: 31c0d1140a131daea2d342121808f6aa0dcd879d
flutter_fimber: 4a6b342666fecb329fca23143f4b72c46cdd8022
Expand Down Expand Up @@ -320,7 +320,7 @@ SPEC CHECKSUMS:
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028
shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
sqlite3: fd89671d969f3e73efe503ce203e28b016b58f68
sqlite3_flutter_libs: 04ba0d14a04335a2fbf9a331e8664f401fbccdd5
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
Expand Down
4 changes: 3 additions & 1 deletion lib/bloc/input/input_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class InputBloc extends Cubit<InputState> {
// Emit an empty InputState with isLoading to display a loader on UI layer
emit(InputState(isLoading: true));
try {
final parsedInput = await _breezLib.parseInput(input: input);
final parsedInput = await parseInput(input: input);
// Todo: Merge these functions w/o sacrificing readability
_logParsedInput(parsedInput);
return await _handleParsedInput(parsedInput);
Expand Down Expand Up @@ -147,4 +147,6 @@ class InputBloc extends Cubit<InputState> {
_log.i("url: ${parsedInput.url}");
}
}

Future<InputType> parseInput({required String input}) async => await _breezLib.parseInput(input: input);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import 'package:breez_sdk/bridge_generated.dart';
import 'package:breez_translations/breez_translations_locales.dart';
import 'package:c_breez/bloc/input/input_bloc.dart';
import 'package:c_breez/theme/theme_provider.dart' as theme;
import 'package:c_breez/utils/lnurl.dart';
import 'package:c_breez/utils/node_id.dart';
import 'package:c_breez/widgets/flushbar.dart';
import 'package:c_breez/widgets/loader.dart';
import 'package:fimber/fimber.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

final _log = FimberLog("EnterPaymentInfoDialog");

class EnterPaymentInfoDialog extends StatefulWidget {
final GlobalKey paymentItemKey;

Expand All @@ -24,6 +27,9 @@ class EnterPaymentInfoDialogState extends State<EnterPaymentInfoDialog> {
final _paymentInfoFocusNode = FocusNode();

String _scannerErrorMessage = "";
String _validatorErrorMessage = "";

ModalRoute? _loaderRoute;

@override
void initState() {
Expand Down Expand Up @@ -95,12 +101,9 @@ class EnterPaymentInfoDialogState extends State<EnterPaymentInfoDialog> {
style: TextStyle(
color: themeData.primaryTextTheme.headlineMedium!.color,
),
validator: (v) {
var value = v!;
if (parseNodeId(value) == null &&
_decodeInvoice(value) == null &&
!isLightningAddress(value)) {
return texts.payment_info_dialog_error;
validator: (value) {
if (_validatorErrorMessage.isNotEmpty) {
return _validatorErrorMessage;
}
return null;
},
Expand Down Expand Up @@ -151,10 +154,23 @@ class EnterPaymentInfoDialogState extends State<EnterPaymentInfoDialog> {
actions.add(
SimpleDialogOption(
onPressed: (() async {
if (_formKey.currentState!.validate()) {
Navigator.of(context).pop();
final inputBloc = context.read<InputBloc>();
inputBloc.addIncomingInput(_paymentInfoController.text);
final inputBloc = context.read<InputBloc>();
final navigator = Navigator.of(context);
_setLoading(true);

try {
await _validateInput(_paymentInfoController.text);
if (_formKey.currentState!.validate()) {
_setLoading(false);
navigator.pop();
inputBloc.addIncomingInput(_paymentInfoController.text);
}
} catch (error) {
_setLoading(false);
_log.w(error.toString(), ex: error);
_setValidatorErrorMessage(texts.payment_info_dialog_error);
} finally {
_setLoading(false);
}
}),
child: Text(
Expand Down Expand Up @@ -186,17 +202,47 @@ class EnterPaymentInfoDialogState extends State<EnterPaymentInfoDialog> {
setState(() {
_paymentInfoController.text = barcode;
_scannerErrorMessage = "";
_setValidatorErrorMessage("");
});
}

Future<void> _validateInput(String input) async {
final texts = context.texts();
try {
_setValidatorErrorMessage("");
final inputType = await context.read<InputBloc>().parseInput(input: input);
_log.v("Parsed input type: '${inputType.runtimeType.toString()}");
// Can't compare against a list of InputType as runtime type comparison is a bit tricky with binding generated enums
if (!(inputType is InputType_Bolt11 ||
inputType is InputType_LnUrlPay ||
inputType is InputType_LnUrlWithdraw ||
inputType is InputType_LnUrlAuth ||
inputType is InputType_LnUrlError ||
inputType is InputType_NodeId)) {
_setValidatorErrorMessage(texts.payment_info_dialog_error_unsupported_input);
}
} catch (e) {
rethrow;
}
}

_setValidatorErrorMessage(String errorMessage) {
setState(() {
_validatorErrorMessage = errorMessage;
});
_formKey.currentState?.validate();
}

String? _decodeInvoice(String invoiceString) {
String normalized = invoiceString.toLowerCase();
if (normalized.startsWith("lightning:")) {
normalized = normalized.substring(10);
void _setLoading(bool visible) {
if (visible && _loaderRoute == null) {
_loaderRoute = createLoaderRoute(context);
Navigator.of(context).push(_loaderRoute!);
return;
}
if (normalized.startsWith("ln") && !normalized.startsWith("lnurl")) {
return invoiceString;

if (!visible && (_loaderRoute != null && _loaderRoute!.isActive)) {
_loaderRoute!.navigator?.removeRoute(_loaderRoute!);
_loaderRoute = null;
}
return null;
}
}
33 changes: 0 additions & 33 deletions lib/utils/lnurl.dart

This file was deleted.

Loading

0 comments on commit 3b32393

Please sign in to comment.