From d5c3712067b15e9392aef4913d81b67e9027bbc2 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 14:38:10 -0600 Subject: [PATCH 01/11] trim excess digits --- lib/pages/buy_view/buy_form.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 87f2c175d..d3af0c6c6 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -1366,8 +1366,10 @@ class NumericalRangeFormatter extends TextInputFormatter { TextEditingValue oldValue, TextEditingValue newValue, ) { - final TextSelection newSelection = newValue.selection; - String newVal = newValue.text; + TextSelection newSelection = newValue.selection; + String newVal = _BuyFormState.buyWithFiat + ? Decimal.parse(newValue.text).toStringAsFixed(2) + : Decimal.parse(newValue.text).toStringAsFixed(8); if (newValue.text == '') { return newValue; } else { From 957a6d63aef3bc579078a7cedbe57e7b73be584c Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 14:38:24 -0600 Subject: [PATCH 02/11] use internal variable --- lib/pages/buy_view/buy_form.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index d3af0c6c6..504a661d1 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -1400,7 +1400,7 @@ class NumericalRangeFormatter extends TextInputFormatter { : r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$'; // return RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$') - return RegExp(regexString).hasMatch(newValue.text) + return RegExp(regexString).hasMatch(newVal) ? TextEditingValue(text: newVal, selection: newSelection) : oldValue; } From 54d8e90c96f8ff30b548690477d306e0b59111c5 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:10:59 -0600 Subject: [PATCH 03/11] deprettify error messages --- lib/pages/buy_view/buy_form.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 504a661d1..ebc5ac48e 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -476,8 +476,7 @@ class _BuyFormState extends ConsumerState { } else { return StackDialog( title: "Simplex API error", - message: - "${quoteResponse.exception?.errorMessage.substring(19, quoteResponse.exception?.errorMessage?.length ?? 109 - (14 + 19))}", + message: "${quoteResponse.exception?.errorMessage}", rightButton: TextButton( style: Theme.of(context) .extension()! @@ -565,7 +564,8 @@ class _BuyFormState extends ConsumerState { } else { return StackDialog( title: "Simplex API error", - message: errorMessage, + message: "${quoteResponse.exception?.errorMessage}", + // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", rightButton: TextButton( style: Theme.of(context) .extension()! From 7c0bfce3c2026fc030978a8671063837e24b6be0 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:11:29 -0600 Subject: [PATCH 04/11] clear field to minimum value --- lib/pages/buy_view/buy_form.dart | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index ebc5ac48e..cc4bd88f0 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -1016,11 +1016,20 @@ class _BuyFormState extends ConsumerState { _buyAmountController.text.isNotEmpty ? TextFieldIconButton( key: const Key( - "buyViewClearAddressFieldButtonKey"), + "buyViewClearAmountFieldButtonKey"), onTap: () { - _buyAmountController.text = ""; - // _receiveAddress = ""; - setState(() {}); + if (_BuyFormState.buyWithFiat) { + _buyAmountController.text = _BuyFormState + .minFiat + .toStringAsFixed(2); + } else { + if (selectedCrypto?.ticker == + _BuyFormState.boundedCryptoTicker) { + _buyAmountController.text = _BuyFormState + .minCrypto + .toStringAsFixed(8); + } + } }, child: const XIcon(), ) From ff5d5784a15f15976d1e04f79a94b5f0935059d5 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:15:14 -0600 Subject: [PATCH 05/11] use min amounts as default text --- lib/pages/buy_view/buy_form.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index cc4bd88f0..365b8bc94 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -936,7 +936,10 @@ class _BuyFormState extends ConsumerState { color: Theme.of(context).extension()!.textDark, ), key: const Key("buyAmountInputFieldTextFieldKey"), - controller: _buyAmountController..text = '50.00', + controller: _buyAmountController + ..text = _BuyFormState.buyWithFiat + ? _BuyFormState.minFiat.toStringAsFixed(2) ?? '50.00' + : _BuyFormState.minCrypto.toStringAsFixed(8), focusNode: _buyAmountFocusNode, keyboardType: Util.isDesktop ? null From ec64c77c45de7a245f5bd0c07ffd2595d6c21db3 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:23:14 -0600 Subject: [PATCH 06/11] comment update --- lib/services/buy/simplex/simplex_api.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 1726d55aa..8b6fdb05f 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -16,7 +16,7 @@ import 'package:url_launcher/url_launcher.dart'; class SimplexAPI { static const String authority = "simplex-sandbox.stackwallet.com"; - // static const String authority = "localhost"; + // static const String authority = "localhost"; // For development purposes static const String scheme = authority == "localhost" ? "http" : "https"; final _prefs = Prefs.instance; From 26dfaa065a66d4db14679166e00d80a531816e58 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:32:23 -0600 Subject: [PATCH 07/11] don't set errorMessage as substring except for >max crypto amt errors --- lib/pages/buy_view/buy_form.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 365b8bc94..525aa5e83 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -500,10 +500,10 @@ class _BuyFormState extends ConsumerState { } else { // Error; probably amount out of bounds String errorMessage = "${quoteResponse.exception?.errorMessage}"; - errorMessage = errorMessage.substring( - (errorMessage.indexOf('getQuote exception: ') ?? 19) + 20, - errorMessage.indexOf(", value: null")); if (errorMessage.contains('must be between')) { + errorMessage = errorMessage.substring( + (errorMessage.indexOf('getQuote exception: ') ?? 19) + 20, + errorMessage.indexOf(", value: null")); _BuyFormState.boundedCryptoTicker = errorMessage.substring( errorMessage.indexOf('The ') + 4, errorMessage.indexOf(' amount must be between')); From 679c382106ac3ec90d56ad277205d63978545990 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 15:54:37 -0600 Subject: [PATCH 08/11] pass, catch, and display error dialog from newOrder --- .../sub_widgets/buy_warning_popup.dart | 100 ++++++++++++++---- lib/services/buy/simplex/simplex_api.dart | 4 + 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart index 082a19306..4b99a66d8 100644 --- a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart +++ b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart @@ -29,18 +29,9 @@ class BuyWarningPopup extends StatelessWidget { SimplexOrder? order; Future> newOrder(SimplexQuote quote) async { - final response = await SimplexAPI.instance.newOrder(quote); + final orderResponse = await SimplexAPI.instance.newOrder(quote); - // if (response.value != null) { - // ref.read(simplexProvider).updateOrder(response.value!); - // } else { - // Logging.instance.log( - // "_loadQuote: $response", - // level: LogLevel.Warning, - // ); - // } - - return response; + return orderResponse; } Future> redirect(SimplexOrder order) async { @@ -122,13 +113,86 @@ class BuyWarningPopup extends StatelessWidget { rightButton: PrimaryButton( label: "Continue", onPressed: () async { - BuyResponse order = await newOrder(quote); - await redirect(order.value as SimplexOrder).then((_response) async { - this.order = order.value as SimplexOrder; - Navigator.of(context, rootNavigator: isDesktop).pop(); - Navigator.of(context, rootNavigator: isDesktop).pop(); - await _buyInvoice(); - }); + BuyResponse orderResponse = await newOrder(quote); + if (orderResponse.exception == null) { + await redirect(orderResponse.value as SimplexOrder) + .then((_response) async { + this.order = orderResponse.value as SimplexOrder; + Navigator.of(context, rootNavigator: isDesktop).pop(); + Navigator.of(context, rootNavigator: isDesktop).pop(); + await _buyInvoice(); + }); + } else { + await showDialog( + context: context, + barrierDismissible: true, + builder: (context) { + if (isDesktop) { + return DesktopDialog( + maxWidth: 450, + child: Padding( + padding: const EdgeInsets.all(32), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Simplex API error", + style: STextStyles.desktopH3(context), + ), + const SizedBox( + height: 24, + ), + Text( + "${orderResponse.exception?.errorMessage}", + style: STextStyles.smallMed14(context), + ), + const SizedBox( + height: 56, + ), + Row( + children: [ + const Spacer(), + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + label: "Ok", + onPressed: Navigator.of(context).pop, + ), + ), + ], + ) + ], + ), + ), + ); + } else { + return StackDialog( + title: "Simplex API error", + message: "${orderResponse.exception?.errorMessage}", + // "${quoteResponse.exception?.errorMessage.substring(8, (quoteResponse.exception?.errorMessage?.length ?? 109) - (8 + 6))}", + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorDark), + ), + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, + ), + ); + } + }, + ); + } }, ), icon: SizedBox( diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 8b6fdb05f..0b6666fa3 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -273,6 +273,10 @@ class SimplexAPI { throw Exception('newOrder exception: statusCode= ${res.statusCode}'); } final jsonArray = jsonDecode(res.body); // TODO check if valid json + if (jsonArray['error'] == true || jsonArray['error'] == 'true') { + print('error'); + throw Exception(jsonArray['message']); + } SimplexOrder _order = SimplexOrder( quote: quote, From ad5f9b3de48ae5e69f515e55a5cc478829c11af6 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 16:05:57 -0600 Subject: [PATCH 09/11] pop thrice --- lib/pages/buy_view/sub_widgets/buy_warning_popup.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart index 4b99a66d8..c98d53580 100644 --- a/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart +++ b/lib/pages/buy_view/sub_widgets/buy_warning_popup.dart @@ -157,7 +157,11 @@ class BuyWarningPopup extends StatelessWidget { child: PrimaryButton( buttonHeight: ButtonHeight.l, label: "Ok", - onPressed: Navigator.of(context).pop, + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + Navigator.of(context).pop(); // weee + }, ), ), ], From 177eb70d516fee4fec799ae4b9d87e51b6150496 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 16:08:56 -0600 Subject: [PATCH 10/11] handle errors more reliably --- lib/services/buy/simplex/simplex_api.dart | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart index 0b6666fa3..4060567f0 100644 --- a/lib/services/buy/simplex/simplex_api.dart +++ b/lib/services/buy/simplex/simplex_api.dart @@ -188,7 +188,10 @@ class SimplexAPI { } final jsonArray = jsonDecode(res.body); if (jsonArray.containsKey('error') as bool) { - throw Exception('getQuote exception: ${jsonArray['error']}'); + if (jsonArray['error'] == true || jsonArray['error'] == 'true') { + // jsonArray['error'] as bool == true? + throw Exception('getQuote exception: ${jsonArray['error']}'); + } } jsonArray['quote'] = quote; // Add and pass this on @@ -273,10 +276,11 @@ class SimplexAPI { throw Exception('newOrder exception: statusCode= ${res.statusCode}'); } final jsonArray = jsonDecode(res.body); // TODO check if valid json + if (jsonArray.containsKey('error') as bool) { if (jsonArray['error'] == true || jsonArray['error'] == 'true') { - print('error'); throw Exception(jsonArray['message']); } + } SimplexOrder _order = SimplexOrder( quote: quote, From 93dc37eed9566781acaccae0a85a7414c17c4c45 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 27 Jan 2023 16:18:13 -0600 Subject: [PATCH 11/11] comment update --- lib/pages/buy_view/buy_form.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart index 525aa5e83..029bc9aa4 100644 --- a/lib/pages/buy_view/buy_form.dart +++ b/lib/pages/buy_view/buy_form.dart @@ -98,9 +98,11 @@ class _BuyFormState extends ConsumerState { bool _hovering1 = false; bool _hovering2 = false; + // TODO actually check USD min and max, these could get updated by Simplex static Decimal minFiat = Decimal.fromInt(50); static Decimal maxFiat = Decimal.fromInt(20000); + // We can't get crypto min and max without asking for a quote static Decimal minCrypto = Decimal.parse((0.00000001) .toString()); // lol how to go from double->Decimal more easily? static Decimal maxCrypto = Decimal.parse((10000.00000000).toString());