Skip to content

Commit

Permalink
add error handling when channel creation is not possible
Browse files Browse the repository at this point in the history
  • Loading branch information
ubbabeck committed Aug 18, 2023
1 parent 40edc14 commit b369b3a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 22 deletions.
8 changes: 8 additions & 0 deletions lib/bloc/account/account_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:c_breez/bloc/account/credentials_manager.dart';
import 'package:c_breez/bloc/account/payment_error.dart';
import 'package:c_breez/bloc/account/payment_filters.dart';
import 'package:c_breez/bloc/account/payment_result.dart';
import 'package:c_breez/bloc/lsp/lsp_state.dart';
import 'package:c_breez/config.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:fimber/fimber.dart';
Expand Down Expand Up @@ -221,6 +222,7 @@ class AccountBloc extends Cubit<AccountState> with HydratedMixin {
int amount,
bool outgoing, {
int? channelMinimumFee,
bool? channelCreationPossible,
}) {
_log.v("validatePayment: $amount, $outgoing, $channelMinimumFee");
var accState = state;
Expand All @@ -230,6 +232,12 @@ class AccountBloc extends Cubit<AccountState> with HydratedMixin {
}

if (!outgoing) {
if (channelCreationPossible != null && !channelCreationPossible && accState.maxInboundLiquidity == 0) {
throw NoChannelCreationZeroLiqudityError();
}
if (channelCreationPossible != null && !channelCreationPossible && accState.maxInboundLiquidity <= 0) {
throw PaymentExcededLiqudityChannelCreationNotPossibleError(accState.maxInboundLiquidity);
}
if (channelMinimumFee != null &&
(amount > accState.maxInboundLiquidity && amount <= channelMinimumFee)) {
throw PaymentBelowSetupFeesError(channelMinimumFee);
Expand Down
10 changes: 10 additions & 0 deletions lib/bloc/account/payment_error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,13 @@ class PaymentExceedLiquidityError implements Exception {
this.limitSat,
);
}

class PaymentExcededLiqudityChannelCreationNotPossibleError implements Exception {
final int limitSat;

const PaymentExcededLiqudityChannelCreationNotPossibleError(
this.limitSat,
);
}

class ChannelCreationNotZeroLiqudityError implements Exception {}
38 changes: 28 additions & 10 deletions lib/routes/create_invoice/create_invoice_page.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:breez_sdk/bridge_generated.dart';
import 'package:breez_translations/breez_translations_locales.dart';
import 'package:c_breez/bloc/account/account_bloc.dart';
Expand All @@ -13,6 +14,7 @@ import 'package:c_breez/routes/create_invoice/widgets/successful_payment.dart';
import 'package:c_breez/routes/lnurl/widgets/lnurl_page_result.dart';
import 'package:c_breez/routes/lnurl/withdraw/lnurl_withdraw_dialog.dart';
import 'package:c_breez/theme/theme_provider.dart' as theme;
import 'package:c_breez/utils/min_font_size.dart';
import 'package:c_breez/utils/payment_validator.dart';
import 'package:c_breez/widgets/amount_form_field/amount_form_field.dart';
import 'package:c_breez/widgets/back_button.dart' as back_button;
Expand All @@ -21,6 +23,7 @@ import 'package:c_breez/widgets/keyboard_done_action.dart';
import 'package:c_breez/widgets/receivable_btc_box.dart';
import 'package:c_breez/widgets/single_button_bottom_bar.dart';
import 'package:c_breez/widgets/transparent_page_route.dart';
import 'package:c_breez/widgets/warning_box.dart';
import 'package:fimber/fimber.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -55,6 +58,7 @@ class CreateInvoicePageState extends State<CreateInvoicePage> {
final _amountController = TextEditingController();
final _amountFocusNode = FocusNode();
var _doneAction = KeyboardDoneAction();
bool channelCreationPossible = false;

@override
void initState() {
Expand All @@ -65,6 +69,12 @@ class CreateInvoicePageState extends State<CreateInvoicePage> {
_amountController.text = (data.maxWithdrawable ~/ 1000).toString();
_descriptionController.text = data.defaultDescription;
}

final lspState = context.read<LSPBloc>().state;
if (lspState != null) {
channelCreationPossible = lspState.isChannelOpeningAvailiable;
}

super.initState();
}

Expand Down Expand Up @@ -124,16 +134,20 @@ class CreateInvoicePageState extends State<CreateInvoicePage> {
builder: (context, accountState, currencyState, lspState) {
return ReceivableBTCBox(
onTap: () {
lspState!.isChannelOpeningAvailiable
? _amountController.text = currencyState.bitcoinCurrency.format(
accountState.maxAllowedToReceive,
includeDisplayName: false,
userInput: true,
)
: _amountController.text = currencyState.bitcoinCurrency.format(
accountState.maxInboundLiquidity,
includeDisplayName: false,
userInput: true);
if (!channelCreationPossible && accountState.maxInboundLiquidity < 0) {
_amountController.text = currencyState.bitcoinCurrency.format(
accountState.maxInboundLiquidity,
includeDisplayName: false,
userInput: true,
);
} else if (!channelCreationPossible && accountState.maxInboundLiquidity > 0) {
// do nothing
} else {
_amountController.text = currencyState.bitcoinCurrency.format(
accountState.maxAllowedToReceive,
includeDisplayName: false,
userInput: true);
}
},
);
},
Expand Down Expand Up @@ -260,6 +274,9 @@ class CreateInvoicePageState extends State<CreateInvoicePage> {
}) {
final data = widget.requestData;
if (data != null) {
if (!channelCreationPossible && amount > data.maxWithdrawable) {
throw PaymentExcededLiqudityChannelCreationNotPossibleError(data.maxWithdrawable ~/ 1000);
}
if (amount > data.maxWithdrawable ~/ 1000) {
throw PaymentExceededLimitError(data.maxWithdrawable ~/ 1000);
}
Expand All @@ -271,6 +288,7 @@ class CreateInvoicePageState extends State<CreateInvoicePage> {
amount,
outgoing,
channelMinimumFee: channelMinimumFee,
channelCreationPossible: channelCreationPossible,
);
}
}
5 changes: 4 additions & 1 deletion lib/utils/payment_validator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class PaymentValidator {
currency.format(e.reserveAmount),
);
} on PaymentExceedLiquidityError catch (e) {
// TODO: Add translation
// TODO(ubbabeck): Add translation
return "Insufficient inbound liquidity (${currency.format(e.limitSat)})";
} on InsufficientLocalBalanceError {
return texts.invoice_payment_validator_error_insufficient_local_balance;
Expand All @@ -60,6 +60,9 @@ class PaymentValidator {
return texts.invoice_payment_validator_error_payment_below_setup_fees_error(
currency.format(e.setupFees),
);
} on PaymentExcededLiqudityChannelCreationNotPossibleError catch (e) {
// TODO(ubbabeck) Add translation
return "Maximum allowed amount to receive is ${e.limitSat}";
} catch (e) {
_log.v("Got Generic error", ex: e);
return texts.invoice_payment_validator_error_unknown(
Expand Down
47 changes: 36 additions & 11 deletions lib/widgets/receivable_btc_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,45 @@ class ReceivableBTCBoxState extends State<ReceivableBTCBox> {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(
widget.receiveLabel ??
texts.invoice_receive_label(
currencyState.bitcoinCurrency.format(
lspState!.isChannelOpeningAvailiable
? accountState.maxAllowedToReceive
: accountState.maxInboundLiquidity,
(accountState.maxInboundLiquidity > 0 &&
lspState != null &&
!lspState!.isChannelOpeningAvailiable)
? AutoSizeText(
widget.receiveLabel ??
texts.invoice_receive_label(
currencyState.bitcoinCurrency.format(
lspState!.isChannelOpeningAvailiable
? accountState.maxAllowedToReceive
: accountState.maxInboundLiquidity,
),
),
style: theme.textStyle,
maxLines: 1,
minFontSize: MinFontSize(context).minFontSize,
)
: const WarningBox(
boxPadding: EdgeInsets.only(top: 8),
child: AutoSizeText(
// TODO(ubbabeck) add translations
"Channel creation not possible cannot receive funds. Please try again later, contact or change your LSP provider.",
textAlign: TextAlign.center,
),
),
style: theme.textStyle,
maxLines: 1,
minFontSize: MinFontSize(context).minFontSize,
),
accountState.isFeesApplicable ? FeeMessage() : const SizedBox(),
(lspState != null &&
!lspState!.isChannelOpeningAvailiable &&
accountState.maxInboundLiquidity < 0)
? WarningBox(
boxPadding: const EdgeInsets.only(top: 22),
contentPadding: const EdgeInsets.all(8),
child: AutoSizeText(
// TODO(ubbabeck) add translations
"LSP cannot open channel now. Retry later. Maximum allowed to receive: ${currencyState.bitcoinCurrency.format(accountState.maxInboundLiquidity)}.",
textAlign: TextAlign.center,
minFontSize: MinFontSize(context).minFontSize,
),
)
: const SizedBox(),
],
),
),
Expand Down

0 comments on commit b369b3a

Please sign in to comment.