diff --git a/lib/bloc/account/account_bloc.dart b/lib/bloc/account/account_bloc.dart index 94be08bcc..8aa4d6794 100644 --- a/lib/bloc/account/account_bloc.dart +++ b/lib/bloc/account/account_bloc.dart @@ -20,7 +20,7 @@ import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; import 'package:rxdart/rxdart.dart'; -const maxPaymentAmount = 4294967; +const maxPaymentAmountSat = 4294967; const nodeSyncInterval = 60; final _log = Logger("AccountBloc"); @@ -160,7 +160,7 @@ class AccountBloc extends Cubit with HydratedMixin { Future lnurlWithdraw({ required sdk.LnUrlWithdrawRequest req, }) async { - _log.info("lnurlWithdraw amount: req: $req"); + _log.info("lnurlWithdraw req: $req"); try { return await _breezSDK.lnurlWithdraw(req: req); } catch (e) { @@ -170,7 +170,7 @@ class AccountBloc extends Cubit with HydratedMixin { } Future lnurlPay({required req}) async { - _log.info("lnurlPay amount: req: $req"); + _log.info("lnurlPay req: $req"); try { return await _breezSDK.lnurlPay(req: req); } catch (e) { @@ -182,7 +182,7 @@ class AccountBloc extends Cubit with HydratedMixin { Future lnurlAuth({ required sdk.LnUrlAuthRequestData reqData, }) async { - _log.info("lnurlAuth amount: reqData: $reqData"); + _log.info("lnurlAuth reqData: $reqData"); try { return await _breezSDK.lnurlAuth(reqData: reqData); } catch (e) { @@ -238,38 +238,38 @@ class AccountBloc extends Cubit with HydratedMixin { // validatePayment is used to validate that outgoing/incoming payments meet the liquidity // constraints. void validatePayment( - int amount, + int amountSat, bool outgoing, bool channelCreationPossible, { - int? channelMinimumFee, + int? channelMinimumFeeSat, }) { - _log.info("validatePayment: $amount, $outgoing, $channelMinimumFee"); + _log.info("validatePayment: $amountSat, $outgoing, $channelMinimumFeeSat"); var accState = state; - if (amount > accState.maxPaymentAmount) { - _log.info("Amount $amount is bigger than maxPaymentAmount ${accState.maxPaymentAmount}"); - throw PaymentExceededLimitError(accState.maxPaymentAmount); + if (amountSat > accState.maxPaymentAmountSat) { + _log.info("Amount $amountSat is bigger than maxPaymentAmount ${accState.maxPaymentAmountSat}"); + throw PaymentExceededLimitError(accState.maxPaymentAmountSat); } if (!outgoing) { - if (!channelCreationPossible && accState.maxInboundLiquidity == 0) { - throw NoChannelCreationZeroLiqudityError(); - } else if (!channelCreationPossible && accState.maxInboundLiquidity < amount) { - throw PaymentExcededLiqudityChannelCreationNotPossibleError(accState.maxInboundLiquidity); - } else if (channelMinimumFee != null && - (amount > accState.maxInboundLiquidity && amount <= channelMinimumFee)) { - throw PaymentBelowSetupFeesError(channelMinimumFee); - } else if (channelMinimumFee == null && amount > accState.maxInboundLiquidity) { - throw PaymentExceedLiquidityError(accState.maxInboundLiquidity); - } else if (amount > accState.maxAllowedToReceive) { - throw PaymentExceededLimitError(accState.maxAllowedToReceive); + if (!channelCreationPossible && accState.maxInboundLiquiditySat == 0) { + throw NoChannelCreationZeroLiquidityError(); + } else if (!channelCreationPossible && accState.maxInboundLiquiditySat < amountSat) { + throw PaymentExceededLiquidityChannelCreationNotPossibleError(accState.maxInboundLiquiditySat); + } else if (channelMinimumFeeSat != null && + (amountSat > accState.maxInboundLiquiditySat && amountSat <= channelMinimumFeeSat)) { + throw PaymentBelowSetupFeesError(channelMinimumFeeSat); + } else if (channelMinimumFeeSat == null && amountSat > accState.maxInboundLiquiditySat) { + throw PaymentExceededLiquidityError(accState.maxInboundLiquiditySat); + } else if (amountSat > accState.maxAllowedToReceiveSat) { + throw PaymentExceededLimitError(accState.maxAllowedToReceiveSat); } } - if (outgoing && amount > accState.maxAllowedToPay) { - _log.info("Outgoing but amount $amount is bigger than ${accState.maxAllowedToPay}"); - if (accState.reserveAmount > 0) { - _log.info("Reserve amount ${accState.reserveAmount}"); - throw PaymentBelowReserveError(accState.reserveAmount); + if (outgoing && amountSat > accState.maxAllowedToPaySat) { + _log.info("Outgoing but amount $amountSat is bigger than ${accState.maxAllowedToPaySat}"); + if (accState.reserveAmountSat > 0) { + _log.info("Reserve amount ${accState.reserveAmountSat}"); + throw PaymentBelowReserveError(accState.reserveAmountSat); } throw const InsufficientLocalBalanceError(); } diff --git a/lib/bloc/account/account_state.dart b/lib/bloc/account/account_state.dart index 8c4c10541..ffac352c8 100644 --- a/lib/bloc/account/account_state.dart +++ b/lib/bloc/account/account_state.dart @@ -13,15 +13,14 @@ class AccountState { final String? id; final bool initial; final int blockheight; - final int balance; - final int walletBalance; - final int maxAllowedToPay; - final int maxAllowedToReceive; - final int maxPaymentAmount; - final int maxChanReserve; + final int balanceSat; + final int walletBalanceSat; + final int maxAllowedToPaySat; + final int maxAllowedToReceiveSat; + final int maxPaymentAmountSat; + final int maxChanReserveSat; final List connectedPeers; - final int maxInboundLiquidity; - final int onChainFeeRate; + final int maxInboundLiquiditySat; final List payments; final PaymentFilters paymentFilters; final ConnectionStatus? connectionStatus; @@ -31,15 +30,14 @@ class AccountState { required this.id, required this.initial, required this.blockheight, - required this.balance, - required this.walletBalance, - required this.maxAllowedToPay, - required this.maxAllowedToReceive, - required this.maxPaymentAmount, - required this.maxChanReserve, + required this.balanceSat, + required this.walletBalanceSat, + required this.maxAllowedToPaySat, + required this.maxAllowedToReceiveSat, + required this.maxPaymentAmountSat, + required this.maxChanReserveSat, required this.connectedPeers, - required this.maxInboundLiquidity, - required this.onChainFeeRate, + required this.maxInboundLiquiditySat, required this.payments, required this.paymentFilters, required this.connectionStatus, @@ -51,15 +49,14 @@ class AccountState { id: null, initial: true, blockheight: 0, - maxAllowedToPay: 0, - maxAllowedToReceive: 0, - maxPaymentAmount: 0, - maxChanReserve: 0, + maxAllowedToPaySat: 0, + maxAllowedToReceiveSat: 0, + maxPaymentAmountSat: 0, + maxChanReserveSat: 0, connectedPeers: List.empty(), - maxInboundLiquidity: 0, - onChainFeeRate: 0, - balance: 0, - walletBalance: 0, + maxInboundLiquiditySat: 0, + balanceSat: 0, + walletBalanceSat: 0, payments: [], paymentFilters: PaymentFilters.initial(), connectionStatus: null, @@ -70,15 +67,14 @@ class AccountState { String? id, bool? initial, int? blockheight, - int? balance, - int? walletBalance, - int? maxAllowedToPay, - int? maxAllowedToReceive, - int? maxPaymentAmount, - int? maxChanReserve, + int? balanceSat, + int? walletBalanceSat, + int? maxAllowedToPaySat, + int? maxAllowedToReceiveSat, + int? maxPaymentAmountSat, + int? maxChanReserveSat, List? connectedPeers, - int? maxInboundLiquidity, - int? onChainFeeRate, + int? maxInboundLiquiditySat, List? payments, PaymentFilters? paymentFilters, ConnectionStatus? connectionStatus, @@ -87,16 +83,15 @@ class AccountState { return AccountState( id: id ?? this.id, initial: initial ?? this.initial, - balance: balance ?? this.balance, - walletBalance: walletBalance ?? this.walletBalance, - maxAllowedToPay: maxAllowedToPay ?? this.maxAllowedToPay, - maxAllowedToReceive: maxAllowedToReceive ?? this.maxAllowedToReceive, - maxPaymentAmount: maxPaymentAmount ?? this.maxPaymentAmount, + balanceSat: balanceSat ?? this.balanceSat, + walletBalanceSat: walletBalanceSat ?? this.walletBalanceSat, + maxAllowedToPaySat: maxAllowedToPaySat ?? this.maxAllowedToPaySat, + maxAllowedToReceiveSat: maxAllowedToReceiveSat ?? this.maxAllowedToReceiveSat, + maxPaymentAmountSat: maxPaymentAmountSat ?? this.maxPaymentAmountSat, blockheight: blockheight ?? this.blockheight, - maxChanReserve: maxChanReserve ?? this.maxChanReserve, + maxChanReserveSat: maxChanReserveSat ?? this.maxChanReserveSat, connectedPeers: connectedPeers ?? this.connectedPeers, - maxInboundLiquidity: maxInboundLiquidity ?? this.maxInboundLiquidity, - onChainFeeRate: onChainFeeRate ?? this.onChainFeeRate, + maxInboundLiquiditySat: maxInboundLiquiditySat ?? this.maxInboundLiquiditySat, payments: payments ?? this.payments, paymentFilters: paymentFilters ?? this.paymentFilters, connectionStatus: connectionStatus ?? this.connectionStatus, @@ -104,9 +99,9 @@ class AccountState { ); } - int get reserveAmount => balance - maxAllowedToPay; + int get reserveAmountSat => balanceSat - maxAllowedToPaySat; - bool get isFeesApplicable => maxAllowedToReceive > maxInboundLiquidity; + bool get isFeesApplicable => maxAllowedToReceiveSat > maxInboundLiquiditySat; // TODO: Add payments toJson Map? toJson() { @@ -114,14 +109,13 @@ class AccountState { "id": id, "initial": initial, "blockheight": blockheight, - "balance": balance, - "walletBalance": walletBalance, - "maxAllowedToPay": maxAllowedToPay, - "maxAllowedToReceive": maxAllowedToReceive, - "maxPaymentAmount": maxPaymentAmount, - "maxChanReserve": maxChanReserve, - "maxInboundLiquidity": maxInboundLiquidity, - "onChainFeeRate": onChainFeeRate, + "balanceSat": balanceSat, + "walletBalanceSat": walletBalanceSat, + "maxAllowedToPaySat": maxAllowedToPaySat, + "maxAllowedToReceiveSat": maxAllowedToReceiveSat, + "maxPaymentAmountSat": maxPaymentAmountSat, + "maxChanReserveSat": maxChanReserveSat, + "maxInboundLiquiditySat": maxInboundLiquiditySat, "paymentFilters": paymentFilters.toJson(), "connectionStatus": connectionStatus?.index, "verificationStatus": verificationStatus?.index, @@ -134,15 +128,14 @@ class AccountState { id: json["id"], initial: json["initial"], blockheight: json["blockheight"], - balance: json["balance"], - walletBalance: json["walletBalance"], - maxAllowedToPay: json["maxAllowedToPay"], - maxAllowedToReceive: json["maxAllowedToReceive"], - maxPaymentAmount: json["maxPaymentAmount"], - maxChanReserve: json["maxChanReserve"], + balanceSat: json["balanceSat"], + walletBalanceSat: json["walletBalanceSat"], + maxAllowedToPaySat: json["maxAllowedToPaySat"], + maxAllowedToReceiveSat: json["maxAllowedToReceiveSat"], + maxPaymentAmountSat: json["maxPaymentAmountSat"], + maxChanReserveSat: json["maxChanReserveSat"], connectedPeers: [], - maxInboundLiquidity: json["maxInboundLiquidity"] ?? 0, - onChainFeeRate: (json["onChainFeeRate"]), + maxInboundLiquiditySat: json["maxInboundLiquiditySat"] ?? 0, payments: [], paymentFilters: PaymentFilters.fromJson(json["paymentFilters"]), connectionStatus: json["connectionStatus"] != null diff --git a/lib/bloc/account/account_state_assembler.dart b/lib/bloc/account/account_state_assembler.dart index 8beb0fade..1235b5233 100644 --- a/lib/bloc/account/account_state_assembler.dart +++ b/lib/bloc/account/account_state_assembler.dart @@ -23,15 +23,14 @@ AccountState? assembleAccountState( id: nodeState.id, initial: false, blockheight: nodeState.blockHeight, - balance: nodeState.channelsBalanceMsat.toInt() ~/ 1000, - walletBalance: nodeState.onchainBalanceMsat ~/ 1000, - maxAllowedToPay: nodeState.maxPayableMsat ~/ 1000, - maxAllowedToReceive: nodeState.maxReceivableMsat ~/ 1000, - maxPaymentAmount: maxPaymentAmount, - maxChanReserve: (nodeState.channelsBalanceMsat.toInt() - nodeState.maxPayableMsat.toInt()) ~/ 1000, + balanceSat: nodeState.channelsBalanceMsat.toInt() ~/ 1000, + walletBalanceSat: nodeState.onchainBalanceMsat ~/ 1000, + maxAllowedToPaySat: nodeState.maxPayableMsat ~/ 1000, + maxAllowedToReceiveSat: nodeState.maxReceivableMsat ~/ 1000, + maxPaymentAmountSat: maxPaymentAmountSat, + maxChanReserveSat: (nodeState.channelsBalanceMsat.toInt() - nodeState.maxPayableMsat.toInt()) ~/ 1000, connectedPeers: nodeState.connectedPeers, - onChainFeeRate: 0, - maxInboundLiquidity: nodeState.inboundLiquidityMsats ~/ 1000, + maxInboundLiquiditySat: nodeState.inboundLiquidityMsats ~/ 1000, payments: payments.map((e) => PaymentMinutiae.fromPayment(e, texts)).toList(), paymentFilters: paymentFilters, connectionStatus: ConnectionStatus.CONNECTED, diff --git a/lib/bloc/account/payment_error.dart b/lib/bloc/account/payment_error.dart index 349ef036d..346cdf0b4 100644 --- a/lib/bloc/account/payment_error.dart +++ b/lib/bloc/account/payment_error.dart @@ -1,25 +1,19 @@ class PaymentExceededLimitError implements Exception { final int limitSat; - const PaymentExceededLimitError( - this.limitSat, - ); + const PaymentExceededLimitError(this.limitSat); } class PaymentBelowLimitError implements Exception { final int limitSat; - const PaymentBelowLimitError( - this.limitSat, - ); + const PaymentBelowLimitError(this.limitSat); } class PaymentBelowReserveError implements Exception { - final int reserveAmount; + final int reserveAmountSat; - const PaymentBelowReserveError( - this.reserveAmount, - ); + const PaymentBelowReserveError(this.reserveAmountSat); } class InsufficientLocalBalanceError implements Exception { @@ -27,27 +21,21 @@ class InsufficientLocalBalanceError implements Exception { } class PaymentBelowSetupFeesError implements Exception { - final int setupFees; + final int setupFeesSat; - const PaymentBelowSetupFeesError( - this.setupFees, - ); + const PaymentBelowSetupFeesError(this.setupFeesSat); } -class PaymentExceedLiquidityError implements Exception { +class PaymentExceededLiquidityError implements Exception { final int limitSat; - const PaymentExceedLiquidityError( - this.limitSat, - ); + const PaymentExceededLiquidityError(this.limitSat); } -class PaymentExcededLiqudityChannelCreationNotPossibleError implements Exception { +class PaymentExceededLiquidityChannelCreationNotPossibleError implements Exception { final int limitSat; - const PaymentExcededLiqudityChannelCreationNotPossibleError( - this.limitSat, - ); + const PaymentExceededLiquidityChannelCreationNotPossibleError(this.limitSat); } -class NoChannelCreationZeroLiqudityError implements Exception {} +class NoChannelCreationZeroLiquidityError implements Exception {} diff --git a/lib/bloc/currency/currency_state.dart b/lib/bloc/currency/currency_state.dart index 798d2815d..d2a73aa70 100644 --- a/lib/bloc/currency/currency_state.dart +++ b/lib/bloc/currency/currency_state.dart @@ -9,12 +9,13 @@ class CurrencyState { final Map exchangeRates; final List fiatCurrenciesData; - CurrencyState( - {this.fiatCurrenciesData = const [], - this.exchangeRates = const {}, - this.preferredCurrencies = const ["USD", "EUR", "GBP", "JPY"], - this.fiatId = "USD", - this.bitcoinTicker = "SAT"}); + CurrencyState({ + this.fiatCurrenciesData = const [], + this.exchangeRates = const {}, + this.preferredCurrencies = const ["USD", "EUR", "GBP", "JPY"], + this.fiatId = "USD", + this.bitcoinTicker = "SAT", + }); CurrencyState.initial() : this(); diff --git a/lib/bloc/refund/refund_bloc.dart b/lib/bloc/refund/refund_bloc.dart index aac0649e3..2c311c19d 100644 --- a/lib/bloc/refund/refund_bloc.dart +++ b/lib/bloc/refund/refund_bloc.dart @@ -114,11 +114,11 @@ class RefundBloc extends Cubit { toAddress: toAddress, satPerVbyte: recommendedFee, ); - final fee = await _prepareRefund(req); + final refundTxFeeSat = await _prepareRefund(req); return RefundFeeOption( processingSpeed: ProcessingSpeed.values.elementAt(index), - txFeeSat: fee, + txFeeSat: refundTxFeeSat, satPerVbyte: recommendedFee, ); }), diff --git a/lib/models/bitcoin_address_info.dart b/lib/models/bitcoin_address_info.dart index f5b2203ea..5d0abe30c 100644 --- a/lib/models/bitcoin_address_info.dart +++ b/lib/models/bitcoin_address_info.dart @@ -16,9 +16,9 @@ class BitcoinAddressInfo { final uri = Uri.tryParse(scannedString); if (uri != null) { address = uri.path; - final amount = uri.queryParameters["amount"]; - if (amount != null) { - final btcAmount = double.tryParse(amount); + final amountSat = uri.queryParameters["amount"]; + if (amountSat != null) { + final btcAmount = double.tryParse(amountSat); if (btcAmount != null) { satAmount = BitcoinCurrency.BTC.toSats(btcAmount); } diff --git a/lib/models/currency.dart b/lib/models/currency.dart index 5d4f46eea..b28dfa430 100644 --- a/lib/models/currency.dart +++ b/lib/models/currency.dart @@ -17,17 +17,20 @@ class BitcoinCurrency extends Object { } String format( - int sat, { + int amountSat, { includeCurrencySymbol = false, includeDisplayName = true, removeTrailingZeros = false, userInput = false, }) => - BitcoinCurrencyFormatter().format(sat, this, - addCurrencySymbol: includeCurrencySymbol, - addCurrencySuffix: includeDisplayName, - removeTrailingZeros: removeTrailingZeros, - userInput: userInput); + BitcoinCurrencyFormatter().format( + amountSat, + this, + addCurrencySymbol: includeCurrencySymbol, + addCurrencySuffix: includeDisplayName, + removeTrailingZeros: removeTrailingZeros, + userInput: userInput, + ); int parse(String amountStr) => BitcoinCurrencyFormatter().parse(amountStr, this); diff --git a/lib/models/fee_options/fee_option.dart b/lib/models/fee_options/fee_option.dart index ce4ca0651..fa384c2ff 100644 --- a/lib/models/fee_options/fee_option.dart +++ b/lib/models/fee_options/fee_option.dart @@ -32,7 +32,7 @@ abstract class FeeOption { } } - bool isAffordable({int? balance, int? walletBalance, required int amountSat}); + bool isAffordable({int? balanceSat, int? walletBalanceSat, required int amountSat}); } class ReverseSwapFeeOption extends FeeOption { @@ -46,10 +46,10 @@ class ReverseSwapFeeOption extends FeeOption { }); @override - bool isAffordable({int? balance, int? walletBalance, required int amountSat}) { - assert(balance != null); + bool isAffordable({int? balanceSat, int? walletBalanceSat, required int amountSat}) { + assert(balanceSat != null); - return balance! >= pairInfo.senderAmountSat; + return balanceSat! >= pairInfo.senderAmountSat; } } @@ -61,7 +61,7 @@ class RefundFeeOption extends FeeOption { }); @override - bool isAffordable({int? balance, int? walletBalance, required int amountSat}) { + bool isAffordable({int? balanceSat, int? walletBalanceSat, required int amountSat}) { return (amountSat >= txFeeSat); } } @@ -74,9 +74,9 @@ class RedeemOnchainFeeOption extends FeeOption { }); @override - bool isAffordable({int? balance, int? walletBalance, required int amountSat}) { - assert(walletBalance != null); + bool isAffordable({int? balanceSat, int? walletBalanceSat, required int amountSat}) { + assert(walletBalanceSat != null); - return (walletBalance! >= amountSat); + return (walletBalanceSat! >= amountSat); } } diff --git a/lib/routes/buy_bitcoin/widgets/lsp_fee_dialog.dart b/lib/routes/buy_bitcoin/widgets/lsp_fee_dialog.dart index 2c18b9926..97b9bbdf8 100644 --- a/lib/routes/buy_bitcoin/widgets/lsp_fee_dialog.dart +++ b/lib/routes/buy_bitcoin/widgets/lsp_fee_dialog.dart @@ -30,17 +30,17 @@ String formatFeeMessage(BuildContext context, OpeningFeeParams openingFeeParams) final currencyState = context.read().state; final accountState = context.read().state; - final minFee = openingFeeParams.minMsat ~/ 1000; - final minFeeFormatted = currencyState.bitcoinCurrency.format(minFee); - final minFeeAboveZero = minFee > 0; + final minFeeSat = openingFeeParams.minMsat ~/ 1000; + final minFeeFormatted = currencyState.bitcoinCurrency.format(minFeeSat); + final minFeeAboveZero = minFeeSat > 0; final setUpFee = (openingFeeParams.proportional / 10000).toString(); final liquidity = currencyState.bitcoinCurrency.format( - accountState.maxInboundLiquidity, + accountState.maxInboundLiquiditySat, ); - final liquidityAboveZero = accountState.maxInboundLiquidity > 0; + final liquidityAboveZero = accountState.maxInboundLiquiditySat > 0; if (minFeeAboveZero && liquidityAboveZero) { - // A setup fee of {setUpFee}% with a minimum of {minFee} will be applied for receiving more than {liquidity} + // A setup fee of {setUpFee}% with a minimum of {minFeeSat} will be applied for receiving more than {liquidity} return texts.moonpay_fee_warning_with_min_fee_account_connected( setUpFee, minFeeFormatted, @@ -53,7 +53,7 @@ String formatFeeMessage(BuildContext context, OpeningFeeParams openingFeeParams) liquidity, ); } else if (minFeeAboveZero && !liquidityAboveZero) { - // A setup fee of {setUpFee}% with a minimum of {minFee} will be applied on the received amount. + // A setup fee of {setUpFee}% with a minimum of {minFeeSat} will be applied on the received amount. return texts.moonpay_fee_warning_with_min_fee_account_not_connected( setUpFee, minFeeFormatted, diff --git a/lib/routes/create_invoice/create_invoice_page.dart b/lib/routes/create_invoice/create_invoice_page.dart index e855a85d9..2334e74d5 100644 --- a/lib/routes/create_invoice/create_invoice_page.dart +++ b/lib/routes/create_invoice/create_invoice_page.dart @@ -134,17 +134,17 @@ class CreateInvoicePageState extends State { builder: (context, accountState, currencyState, lspState) { return ReceivableBTCBox( onTap: () { - if (!isChannelOpeningAvailable && accountState.maxInboundLiquidity > 0) { + if (!isChannelOpeningAvailable && accountState.maxInboundLiquiditySat > 0) { _amountController.text = currencyState.bitcoinCurrency.format( - accountState.maxInboundLiquidity, + accountState.maxInboundLiquiditySat, includeDisplayName: false, userInput: true, ); - } else if (!isChannelOpeningAvailable && accountState.maxInboundLiquidity == 0) { + } else if (!isChannelOpeningAvailable && accountState.maxInboundLiquiditySat == 0) { // do nothing } else { _amountController.text = currencyState.bitcoinCurrency.format( - accountState.maxAllowedToReceive, + accountState.maxAllowedToReceiveSat, includeDisplayName: false, userInput: true, ); @@ -192,7 +192,7 @@ class CreateInvoicePageState extends State { barrierDismissible: false, builder: (_) => LNURLWithdrawDialog( requestData: data, - amountSats: currencyBloc.state.bitcoinCurrency.parse( + amountSat: currencyBloc.state.bitcoinCurrency.parse( _amountController.text, ), onFinish: widget.onFinish!, @@ -253,9 +253,9 @@ class CreateInvoicePageState extends State { } } - String? validatePayment(int amount) { + String? validatePayment(int amountSat) { final lspInfo = context.read().state?.lspInfo; - int? channelMinimumFee = lspInfo != null && lspInfo.openingFeeParamsList.values.isNotEmpty + int? channelMinimumFeeSat = lspInfo != null && lspInfo.openingFeeParamsList.values.isNotEmpty ? lspInfo.openingFeeParamsList.values.first.minMsat ~/ 1000 : null; @@ -263,31 +263,31 @@ class CreateInvoicePageState extends State { validatePayment: _validatePayment, currency: context.read().state.bitcoinCurrency, channelCreationPossible: context.read().state?.isChannelOpeningAvailable ?? false, - channelMinimumFee: channelMinimumFee, + channelMinimumFeeSat: channelMinimumFeeSat, texts: context.texts(), - ).validateIncoming(amount); + ).validateIncoming(amountSat); } void _validatePayment( - int amount, + int amountSat, bool outgoing, bool channelCreationPossible, { - int? channelMinimumFee, + int? channelMinimumFeeSat, }) { final data = widget.requestData; if (data != null) { - if (amount > data.maxWithdrawable ~/ 1000) { + if (amountSat > data.maxWithdrawable ~/ 1000) { throw PaymentExceededLimitError(data.maxWithdrawable ~/ 1000); } - if (amount < data.minWithdrawable ~/ 1000) { + if (amountSat < data.minWithdrawable ~/ 1000) { throw PaymentBelowLimitError(data.minWithdrawable ~/ 1000); } } return context.read().validatePayment( - amount, + amountSat, outgoing, channelCreationPossible, - channelMinimumFee: channelMinimumFee, + channelMinimumFeeSat: channelMinimumFeeSat, ); } } diff --git a/lib/routes/create_invoice/widgets/expiry_and_fee_message.dart b/lib/routes/create_invoice/widgets/expiry_and_fee_message.dart index f07deeaad..91ab8d395 100644 --- a/lib/routes/create_invoice/widgets/expiry_and_fee_message.dart +++ b/lib/routes/create_invoice/widgets/expiry_and_fee_message.dart @@ -33,7 +33,7 @@ class ExpiryAndFeeMessage extends StatelessWidget { (lspFees != null) ? texts.qr_code_dialog_warning_message_with_lsp( currencyState.bitcoinCurrency.format(lspFees! ~/ 1000), - currencyState.fiatConversion()?.format(lspFees! ~/ 1000) ?? "", + currencyState.fiatConversion()?.formatSat(lspFees! ~/ 1000) ?? "", ) : texts.qr_code_dialog_warning_message, textAlign: TextAlign.center, diff --git a/lib/routes/create_invoice/widgets/fee_message.dart b/lib/routes/create_invoice/widgets/fee_message.dart index 648d257ba..9c57fa39d 100644 --- a/lib/routes/create_invoice/widgets/fee_message.dart +++ b/lib/routes/create_invoice/widgets/fee_message.dart @@ -35,17 +35,17 @@ class FeeMessage extends StatelessWidget { final currencyState = context.read().state; final accountState = context.read().state; - final minFee = openingFeeParams.minMsat ~/ 1000; - final minFeeFormatted = currencyState.bitcoinCurrency.format(minFee); - final minFeeAboveZero = minFee > 0; + final minFeeSat = openingFeeParams.minMsat ~/ 1000; + final minFeeFormatted = currencyState.bitcoinCurrency.format(minFeeSat); + final minFeeAboveZero = minFeeSat > 0; final setUpFee = (openingFeeParams.proportional / 10000).toString(); final liquidity = currencyState.bitcoinCurrency.format( - accountState.maxInboundLiquidity, + accountState.maxInboundLiquiditySat, ); - final liquidityAboveZero = accountState.maxInboundLiquidity > 0; + final liquidityAboveZero = accountState.maxInboundLiquiditySat > 0; if (minFeeAboveZero && liquidityAboveZero) { - // A setup fee of {setUpFee}% with a minimum of {minFee} will be applied for receiving more than {liquidity} + // A setup fee of {setUpFee}% with a minimum of {minFeeSat} will be applied for receiving more than {liquidity} return texts.invoice_lightning_warning_with_min_fee_account_connected( setUpFee, minFeeFormatted, @@ -58,7 +58,7 @@ class FeeMessage extends StatelessWidget { liquidity, ); } else if (minFeeAboveZero && !liquidityAboveZero) { - // A setup fee of {setUpFee}% with a minimum of {minFee} will be applied on the received amount. + // A setup fee of {setUpFee}% with a minimum of {minFeeSat} will be applied on the received amount. return texts.invoice_lightning_warning_with_min_fee_account_not_connected( setUpFee, minFeeFormatted, diff --git a/lib/routes/create_invoice/widgets/receivable_btc_box.dart b/lib/routes/create_invoice/widgets/receivable_btc_box.dart index f16bbe7f1..1b30978cf 100644 --- a/lib/routes/create_invoice/widgets/receivable_btc_box.dart +++ b/lib/routes/create_invoice/widgets/receivable_btc_box.dart @@ -46,7 +46,7 @@ class ReceivableBTCBoxState extends State { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - (!isChannelOpeningAvailable && accountState.maxInboundLiquidity <= 0) + (!isChannelOpeningAvailable && accountState.maxInboundLiquiditySat <= 0) ? WarningBox( boxPadding: const EdgeInsets.only(top: 8), child: AutoSizeText( @@ -58,8 +58,8 @@ class ReceivableBTCBoxState extends State { widget.receiveLabel ?? texts.invoice_receive_label( currencyState.bitcoinCurrency.format((isChannelOpeningAvailable) - ? accountState.maxAllowedToReceive - : accountState.maxInboundLiquidity), + ? accountState.maxAllowedToReceiveSat + : accountState.maxInboundLiquiditySat), ), style: theme.textStyle, maxLines: 1, diff --git a/lib/routes/home/widgets/app_bar/account_required_actions.dart b/lib/routes/home/widgets/app_bar/account_required_actions.dart index 95493f2bc..7ee1fa5cd 100644 --- a/lib/routes/home/widgets/app_bar/account_required_actions.dart +++ b/lib/routes/home/widgets/app_bar/account_required_actions.dart @@ -7,10 +7,10 @@ import 'package:c_breez/bloc/ext/block_builder_extensions.dart'; import 'package:c_breez/bloc/lsp/lsp_bloc.dart'; import 'package:c_breez/bloc/lsp/lsp_state.dart'; import 'package:c_breez/bloc/refund/refund_bloc.dart'; +import 'package:c_breez/routes/get-refund/get_refund_page.dart'; import 'package:c_breez/routes/home/widgets/app_bar/warning_action.dart'; import 'package:c_breez/routes/home/widgets/enable_backup_dialog.dart'; import 'package:c_breez/routes/home/widgets/rotator.dart'; -import 'package:c_breez/routes/get-refund/get_refund_page.dart'; import 'package:c_breez/services/injector.dart'; import 'package:c_breez/widgets/backup_in_progress_dialog.dart'; import 'package:flutter/material.dart'; @@ -35,14 +35,14 @@ class AccountRequiredActionsIndicator extends StatelessWidget { final refundState = refundBloc.state; List warnings = []; - int walletBalance = accState.walletBalance; + int walletBalanceSat = accState.walletBalanceSat; - if (walletBalance > 0) { + if (walletBalanceSat > 0) { warnings.add( WarningAction( () => navigatorState.pushNamed( "/unexpected_funds", - arguments: walletBalance, + arguments: walletBalanceSat, ), ), ); diff --git a/lib/routes/home/widgets/dashboard/balance_text.dart b/lib/routes/home/widgets/dashboard/balance_text.dart index b4207a047..c84c2a180 100644 --- a/lib/routes/home/widgets/dashboard/balance_text.dart +++ b/lib/routes/home/widgets/dashboard/balance_text.dart @@ -47,7 +47,7 @@ class _BalanceTextState extends State { fontSize: startSize - (startSize - endSize) * widget.offsetFactor, ), text: widget.currencyState.bitcoinCurrency.format( - widget.accountState.balance, + widget.accountState.balanceSat, removeTrailingZeros: true, includeDisplayName: false, ), diff --git a/lib/routes/home/widgets/dashboard/fiat_balance_text.dart b/lib/routes/home/widgets/dashboard/fiat_balance_text.dart index 97df222ae..c12c9c39d 100644 --- a/lib/routes/home/widgets/dashboard/fiat_balance_text.dart +++ b/lib/routes/home/widgets/dashboard/fiat_balance_text.dart @@ -52,9 +52,9 @@ class _FiatBalanceTextState extends State { ); } }, - child: widget.accountState.balance > 0 + child: widget.accountState.balanceSat > 0 ? Text( - widget.currencyState.fiatConversion()?.format(widget.accountState.balance) ?? "", + widget.currencyState.fiatConversion()?.formatSat(widget.accountState.balanceSat) ?? "", style: theme.balanceFiatConversionTextStyle.copyWith( color: themeData.colorScheme.onSecondary.withOpacity( pow(1.00 - widget.offsetFactor, 2).toDouble(), @@ -91,7 +91,7 @@ class _FiatBalanceTextState extends State { final fiatConversion = currencyState.fiatConversion(); if (fiatConversion == null) return false; - double fiatValue = fiatConversion.satToFiat(accountState.balance); + double fiatValue = fiatConversion.satToFiat(accountState.balanceSat); int fractionSize = fiatConversion.currencyData.info.fractionSize; double minimumAmount = 1 / (pow(10, fractionSize)); diff --git a/lib/routes/home/widgets/payments_list/dialog/payment_details_dialog_amount.dart b/lib/routes/home/widgets/payments_list/dialog/payment_details_dialog_amount.dart index b28b972f1..7a8260159 100644 --- a/lib/routes/home/widgets/payments_list/dialog/payment_details_dialog_amount.dart +++ b/lib/routes/home/widgets/payments_list/dialog/payment_details_dialog_amount.dart @@ -46,13 +46,13 @@ class PaymentDetailsDialogAmount extends StatelessWidget { scrollDirection: Axis.horizontal, reverse: true, child: BlocBuilder(builder: (context, state) { - final amountSats = BitcoinCurrency.fromTickerSymbol( + final amountSat = BitcoinCurrency.fromTickerSymbol( state.bitcoinTicker, ).format(paymentMinutiae.amountSat); return AutoSizeText( paymentMinutiae.paymentType == PaymentType.Received - ? texts.payment_details_dialog_amount_positive(amountSats) - : texts.payment_details_dialog_amount_negative(amountSats), + ? texts.payment_details_dialog_amount_positive(amountSat) + : texts.payment_details_dialog_amount_negative(amountSat), style: themeData.primaryTextTheme.displaySmall, textAlign: TextAlign.right, maxLines: 1, diff --git a/lib/routes/home/widgets/payments_list/payment_item_amount.dart b/lib/routes/home/widgets/payments_list/payment_item_amount.dart index dc884845b..26469c75a 100644 --- a/lib/routes/home/widgets/payments_list/payment_item_amount.dart +++ b/lib/routes/home/widgets/payments_list/payment_item_amount.dart @@ -35,13 +35,13 @@ class PaymentItemAmount extends StatelessWidget { final bool hideBalance = userModel.profileSettings.hideBalance; return BlocBuilder( builder: (context, currencyState) { - final fee = _paymentMinutiae.feeSat; - final amount = currencyState.bitcoinCurrency.format( + final feeSat = _paymentMinutiae.feeSat; + final amountSat = currencyState.bitcoinCurrency.format( _paymentMinutiae.amountSat, includeDisplayName: false, ); final feeFormatted = currencyState.bitcoinCurrency.format( - fee, + feeSat, includeDisplayName: false, ); @@ -56,11 +56,11 @@ class PaymentItemAmount extends StatelessWidget { hideBalance ? texts.wallet_dashboard_payment_item_balance_hide : _paymentMinutiae.paymentType == PaymentType.Received - ? texts.wallet_dashboard_payment_item_balance_positive(amount) - : texts.wallet_dashboard_payment_item_balance_negative(amount), + ? texts.wallet_dashboard_payment_item_balance_positive(amountSat) + : texts.wallet_dashboard_payment_item_balance_negative(amountSat), style: themeData.paymentItemAmountTextStyle, ), - (fee == 0 || _paymentMinutiae.status == PaymentStatus.Pending) + (feeSat == 0 || _paymentMinutiae.status == PaymentStatus.Pending) ? const SizedBox() : Text( hideBalance diff --git a/lib/routes/home/widgets/status_text.dart b/lib/routes/home/widgets/status_text.dart index 01ce71c50..1051ad6f3 100644 --- a/lib/routes/home/widgets/status_text.dart +++ b/lib/routes/home/widgets/status_text.dart @@ -31,7 +31,7 @@ class StatusText extends StatelessWidget { } else { final isChannelOpeningAvailable = lspState!.isChannelOpeningAvailable; return AutoSizeText( - (isChannelOpeningAvailable && accountState.maxInboundLiquidity >= 0) + (isChannelOpeningAvailable && accountState.maxInboundLiquiditySat >= 0) ? texts.status_text_ready : texts.lsp_error_cannot_open_channel, style: themeData.textTheme.bodyMedium?.copyWith( diff --git a/lib/routes/ln_address/ln_address_fee_message.dart b/lib/routes/ln_address/ln_address_fee_message.dart index fb253f49b..0a5d513c2 100644 --- a/lib/routes/ln_address/ln_address_fee_message.dart +++ b/lib/routes/ln_address/ln_address_fee_message.dart @@ -23,7 +23,7 @@ class LnAddressFeeMessage extends StatelessWidget { final isChannelOpeningAvailable = lspState?.isChannelOpeningAvailable ?? false; final openingFeeParams = lspState?.lspInfo?.openingFeeParamsList.values.first; - if (!isChannelOpeningAvailable && accountState.maxInboundLiquidity <= 0) { + if (!isChannelOpeningAvailable && accountState.maxInboundLiquiditySat <= 0) { return WarningBox( boxPadding: const EdgeInsets.fromLTRB(16, 30, 16, 16), child: Column( @@ -63,38 +63,38 @@ class LnAddressFeeMessage extends StatelessWidget { final paymentOptionsState = context.read().state; // Proportional value is ppm(parts per million) final proportionalPercent = (openingFeeParams.proportional / (1000000 / 100)).toString(); - final liquiditySats = accountState.maxInboundLiquidity; - final liquidityFormatted = currencyState.bitcoinCurrency.format(liquiditySats); - final liquidityAboveMin = liquiditySats > 1; + final liquiditySat = accountState.maxInboundLiquiditySat; + final liquidityFormatted = currencyState.bitcoinCurrency.format(liquiditySat); + final liquidityAboveMin = liquiditySat > 1; // Calculate the maximum receivable amount within the fee limit (in millisatoshis) final channelFeeLimitSat = paymentOptionsState.channelFeeLimitMsat ~/ 1000; // Calculate the maximum sendable amount (in sats) - final maxSendableSats = maxReceivableSat(accountState, channelFeeLimitSat, openingFeeParams); - final maxSendableFormatted = currencyState.bitcoinCurrency.format(maxSendableSats); + final maxSendableSat = maxReceivableSat(accountState, channelFeeLimitSat, openingFeeParams); + final maxSendableFormatted = currencyState.bitcoinCurrency.format(maxSendableSat); // Get the minimum sendable amount (in sats), can not be less than 1 or more than maxSendable - final minSendableSats = (liquidityAboveMin) ? 1 : openingFeeParams.minMsat ~/ 1000; - final minSendableAboveMin = minSendableSats >= 1; - final minSendableFormatted = currencyState.bitcoinCurrency.format(minSendableSats); + final minSendableSat = (liquidityAboveMin) ? 1 : openingFeeParams.minMsat ~/ 1000; + final minSendableAboveMin = minSendableSat >= 1; + final minSendableFormatted = currencyState.bitcoinCurrency.format(minSendableSat); if (!minSendableAboveMin) { return "Minimum sendable amount can't be less than ${currencyState.bitcoinCurrency.format(1)}."; } - if (minSendableSats > maxSendableSats) { + if (minSendableSat > maxSendableSat) { return "Minimum sendable amount can't be greater than maximum sendable amount."; } final minFeeFormatted = currencyState.bitcoinCurrency.format(openingFeeParams.minMsat ~/ 1000); - final isFeeApplicable = maxSendableSats > liquiditySats; + final isFeeApplicable = maxSendableSat > liquiditySat; if (!isFeeApplicable) { - // Send more than {minSendableSats} and up to {maxSendableSats} to this address. + // Send more than {minSendableSat} and up to {maxSendableSat} to this address. return texts.invoice_ln_address_channel_not_needed( minSendableFormatted, maxSendableFormatted, ); } else if (liquidityAboveMin) { - // Send more than {minSendableSats} and up to {maxSendableSats} to this address. A setup fee of {proportionalPercent}% with a minimum of {minFeeFormatted} - // will be applied for sending more than {liquiditySats}. + // Send more than {minSendableSat} and up to {maxSendableSat} to this address. A setup fee of {proportionalPercent}% with a minimum of {minFeeFormatted} + // will be applied for sending more than {liquiditySat}. return texts.invoice_ln_address_warning_with_min_fee_account_connected( minSendableFormatted, maxSendableFormatted, @@ -103,7 +103,7 @@ class LnAddressFeeMessage extends StatelessWidget { liquidityFormatted, ); } else { - // Send more than {minSendableSats} and up to {maxSendableSats} to this address. A setup fee of {proportionalPercent}% with a minimum of {minSendableSats} + // Send more than {minSendableSat} and up to {maxSendableSat} to this address. A setup fee of {proportionalPercent}% with a minimum of {minSendableSat} // will be applied on the received amount. return texts.invoice_ln_address_warning_with_min_fee_account_not_connected( minSendableFormatted, @@ -121,15 +121,15 @@ class LnAddressFeeMessage extends StatelessWidget { ) { // Treat fee limit feature as disabled when it's set to 0 if (channelFeeLimitSat != 0) { - int maxAllowedToReceiveSat = account.maxAllowedToReceive; + int maxAllowedToReceiveSat = account.maxAllowedToReceiveSat; // Proportional value is ppm(parts per million) final proportional = openingFeeParams.proportional / (1000000); final maxReceivableSatFeeLimit = (proportional != 0.0 && channelFeeLimitSat != 0) ? min(maxAllowedToReceiveSat, channelFeeLimitSat.toDouble() ~/ proportional).toInt() : maxAllowedToReceiveSat; - return max(account.maxInboundLiquidity, maxReceivableSatFeeLimit); + return max(account.maxInboundLiquiditySat, maxReceivableSatFeeLimit); } else { - return account.maxInboundLiquidity; + return account.maxInboundLiquiditySat; } } } diff --git a/lib/routes/lnurl/payment/lnurl_payment_dialog.dart b/lib/routes/lnurl/payment/lnurl_payment_dialog.dart index 1d380af30..6dda85183 100644 --- a/lib/routes/lnurl/payment/lnurl_payment_dialog.dart +++ b/lib/routes/lnurl/payment/lnurl_payment_dialog.dart @@ -84,7 +84,7 @@ class LNURLPaymentDialogState extends State { ), child: Text( _showFiatCurrency && fiatConversion != null - ? fiatConversion.format(widget.data.maxSendable ~/ 1000) + ? fiatConversion.formatSat(widget.data.maxSendable ~/ 1000) : BitcoinCurrency.fromTickerSymbol(currencyState.bitcoinTicker) .format(widget.data.maxSendable ~/ 1000), style: themeData.primaryTextTheme.headlineSmall, @@ -146,11 +146,16 @@ class LNURLPaymentDialogState extends State { }), ), onPressed: () { - final amount = widget.data.maxSendable ~/ 1000; - _log.info("LNURL payment of $amount sats where " - "min is ${widget.data.minSendable} msats " - "and max is ${widget.data.maxSendable} msats."); - Navigator.pop(context, LNURLPaymentInfo(amount: amount)); + final amountSat = widget.data.maxSendable ~/ 1000; + _log.info( + "LNURL payment of $amountSat sats where " + "min is ${widget.data.minSendable} msats " + "and max is ${widget.data.maxSendable} msats.", + ); + Navigator.pop( + context, + LNURLPaymentInfo(amountSat: amountSat), + ); }, child: Text( texts.spontaneous_payment_action_pay, diff --git a/lib/routes/lnurl/payment/lnurl_payment_handler.dart b/lib/routes/lnurl/payment/lnurl_payment_handler.dart index 6da0a07b1..a96045a18 100644 --- a/lib/routes/lnurl/payment/lnurl_payment_handler.dart +++ b/lib/routes/lnurl/payment/lnurl_payment_handler.dart @@ -19,8 +19,8 @@ Future handlePayRequest( LnUrlPayRequestData data, ) async { LNURLPaymentInfo? paymentInfo; - bool fixedAmount = data.minSendable == data.maxSendable; - if (fixedAmount && !(data.commentAllowed > 0)) { + bool isFixedAmount = data.minSendable == data.maxSendable; + if (isFixedAmount && !(data.commentAllowed > 0)) { // Show dialog if payment is of fixed amount with no payer comment allowed paymentInfo = await showDialog( useRootNavigator: false, @@ -49,7 +49,7 @@ Future handlePayRequest( paymentFunc: () { final accBloc = context.read(); final req = LnUrlPayRequest( - amountMsat: paymentInfo!.amount * 1000, + amountMsat: paymentInfo!.amountSat * 1000, comment: paymentInfo.comment, data: data, validateSuccessActionUrl: false, diff --git a/lib/routes/lnurl/payment/lnurl_payment_info.dart b/lib/routes/lnurl/payment/lnurl_payment_info.dart index f5be96695..246bb72d3 100644 --- a/lib/routes/lnurl/payment/lnurl_payment_info.dart +++ b/lib/routes/lnurl/payment/lnurl_payment_info.dart @@ -1,9 +1,9 @@ class LNURLPaymentInfo { - final int amount; + final int amountSat; final String? comment; const LNURLPaymentInfo({ - required this.amount, + required this.amountSat, this.comment, }); } diff --git a/lib/routes/lnurl/payment/lnurl_payment_page.dart b/lib/routes/lnurl/payment/lnurl_payment_page.dart index 5f4bb7662..17a085870 100644 --- a/lib/routes/lnurl/payment/lnurl_payment_page.dart +++ b/lib/routes/lnurl/payment/lnurl_payment_page.dart @@ -62,15 +62,15 @@ class LNURLPaymentPageState extends State { final _emailController = TextEditingController(); final _identifierController = TextEditingController(); */ - late final bool fixedAmount; + late final bool isFixedAmount; @override void initState() { super.initState(); - fixedAmount = widget.data.minSendable == widget.data.maxSendable; + isFixedAmount = widget.data.minSendable == widget.data.maxSendable; WidgetsBinding.instance.addPostFrameCallback( (_) { - if (fixedAmount) { + if (isFixedAmount) { final currencyState = context.read().state; _amountController.text = currencyState.bitcoinCurrency.format( (widget.data.maxSendable ~/ 1000), @@ -124,10 +124,10 @@ class LNURLPaymentPageState extends State { bitcoinCurrency: currencyState.bitcoinCurrency, controller: _amountController, validatorFn: validatePayment, - enabled: !fixedAmount, - readOnly: fixedAmount, + enabled: !isFixedAmount, + readOnly: isFixedAmount, ), - if (!fixedAmount) ...[ + if (!isFixedAmount) ...[ Padding( padding: const EdgeInsets.only( top: 8, @@ -226,46 +226,54 @@ class LNURLPaymentPageState extends State { onPressed: () async { if (_formKey.currentState!.validate()) { final currencyBloc = context.read(); - final amount = currencyBloc.state.bitcoinCurrency.parse(_amountController.text); + final amountSat = currencyBloc.state.bitcoinCurrency.parse(_amountController.text); final comment = _commentController.text; - _log.info("LNURL payment of $amount sats where " - "min is ${widget.data.minSendable} msats " - "and max is ${widget.data.maxSendable} msats." - "with comment $comment"); - Navigator.pop(context, LNURLPaymentInfo(amount: amount, comment: comment)); + _log.info( + "LNURL payment of $amountSat sats where " + "min is ${widget.data.minSendable} msats " + "and max is ${widget.data.maxSendable} msats." + "with comment $comment", + ); + Navigator.pop( + context, + LNURLPaymentInfo( + amountSat: amountSat, + comment: comment, + ), + ); } }, ), ); } - String? validatePayment(int amount) { + String? validatePayment(int amountSat) { final texts = context.texts(); final accBloc = context.read(); final lspState = context.read().state; final currencyState = context.read().state; - final maxSendable = widget.data.maxSendable ~/ 1000; - if (amount > maxSendable) { - return texts.lnurl_payment_page_error_exceeds_limit(maxSendable); + final maxSendableSat = widget.data.maxSendable ~/ 1000; + if (amountSat > maxSendableSat) { + return texts.lnurl_payment_page_error_exceeds_limit(maxSendableSat); } - final minSendable = widget.data.minSendable ~/ 1000; - if (amount < minSendable) { - return texts.lnurl_payment_page_error_below_limit(minSendable); + final minSendableSat = widget.data.minSendable ~/ 1000; + if (amountSat < minSendableSat) { + return texts.lnurl_payment_page_error_below_limit(minSendableSat); } - int? channelMinimumFee; + int? channelMinimumFeeSat; if (lspState != null && lspState.lspInfo != null) { - channelMinimumFee = lspState.lspInfo!.openingFeeParamsList.values.first.minMsat ~/ 1000; + channelMinimumFeeSat = lspState.lspInfo!.openingFeeParamsList.values.first.minMsat ~/ 1000; } return PaymentValidator( validatePayment: accBloc.validatePayment, currency: currencyState.bitcoinCurrency, channelCreationPossible: lspState?.isChannelOpeningAvailable ?? false, - channelMinimumFee: channelMinimumFee, + channelMinimumFeeSat: channelMinimumFeeSat, texts: context.texts(), - ).validateOutgoing(amount); + ).validateOutgoing(amountSat); } } diff --git a/lib/routes/lnurl/withdraw/lnurl_withdraw_dialog.dart b/lib/routes/lnurl/withdraw/lnurl_withdraw_dialog.dart index 90d3baad6..9b920bd3b 100644 --- a/lib/routes/lnurl/withdraw/lnurl_withdraw_dialog.dart +++ b/lib/routes/lnurl/withdraw/lnurl_withdraw_dialog.dart @@ -14,12 +14,12 @@ final _log = Logger("LNURLWithdrawDialog"); class LNURLWithdrawDialog extends StatefulWidget { final Function(LNURLPageResult? result) onFinish; final sdk.LnUrlWithdrawRequestData requestData; - final int amountSats; + final int amountSat; const LNURLWithdrawDialog({ super.key, required this.requestData, - required this.amountSats, + required this.amountSat, required this.onFinish, }); @@ -134,17 +134,17 @@ class _LNURLWithdrawDialogState extends State with SingleTi } Future _withdraw(BuildContext context) async { - _log.info("Withdraw ${widget.amountSats} sats"); + _log.info("Withdraw ${widget.amountSat} sats"); final texts = context.texts(); final accountBloc = context.read(); final description = widget.requestData.defaultDescription; try { - _log.info("LNURL withdraw of ${widget.amountSats} sats where " + _log.info("LNURL withdraw of ${widget.amountSat} sats where " "min is ${widget.requestData.minWithdrawable} msats " "and max is ${widget.requestData.maxWithdrawable} msats."); final req = sdk.LnUrlWithdrawRequest( - amountMsat: widget.amountSats * 1000, + amountMsat: widget.amountSat * 1000, data: widget.requestData, description: description, ); diff --git a/lib/routes/spontaneous_payment/spontaneous_payment_page.dart b/lib/routes/spontaneous_payment/spontaneous_payment_page.dart index 646d7fe81..117769d45 100644 --- a/lib/routes/spontaneous_payment/spontaneous_payment_page.dart +++ b/lib/routes/spontaneous_payment/spontaneous_payment_page.dart @@ -155,14 +155,14 @@ class SpontaneousPaymentPageState extends State { return GestureDetector( child: AutoSizeText( texts.spontaneous_payment_max_amount( - currencyState.bitcoinCurrency.format(acc.maxAllowedToPay), + currencyState.bitcoinCurrency.format(acc.maxAllowedToPaySat), ), style: theme.textStyle, maxLines: 1, minFontSize: MinFontSize(context).minFontSize, ), onTap: () => _amountController.text = currencyState.bitcoinCurrency.format( - acc.maxAllowedToPay, + acc.maxAllowedToPaySat, includeDisplayName: false, userInput: true, ), @@ -183,14 +183,14 @@ class SpontaneousPaymentPageState extends State { String tipMessage = _descriptionController.text; var bitcoinCurrency = currencyBloc.state.bitcoinCurrency; - var amount = bitcoinCurrency.parse(_amountController.text); + var amountSat = bitcoinCurrency.parse(_amountController.text); _amountFocusNode.unfocus(); await promptAreYouSure( context, texts.spontaneous_payment_send_payment_title, Text( texts.spontaneous_payment_send_payment_message( - bitcoinCurrency.format(amount), + bitcoinCurrency.format(amountSat), widget.nodeID!, ), ), @@ -214,7 +214,7 @@ class SpontaneousPaymentPageState extends State { sendFuture = accBloc.sendSpontaneousPayment( nodeId: widget.nodeID!, description: tipMessage, - amountMsat: amount * 1000, + amountMsat: amountSat * 1000, ); return sendFuture; }, diff --git a/lib/routes/subswap/swap/widgets/deposit_widget.dart b/lib/routes/subswap/swap/widgets/deposit_widget.dart index 2b4b8743b..3fc017dfe 100644 --- a/lib/routes/subswap/swap/widgets/deposit_widget.dart +++ b/lib/routes/subswap/swap/widgets/deposit_widget.dart @@ -90,59 +90,59 @@ class _DepositWidgetState extends State { final minFees = openingFeeParams.minMsat ~/ 1000; final minFeeAboveZero = minFees > 0; final minFeeFormatted = currencyState.bitcoinCurrency.format(minFees); - final minSats = currencyState.bitcoinCurrency.format( + final minSat = currencyState.bitcoinCurrency.format( _minAllowedDeposit( lspInfo, minAllowedDeposit, ), includeDisplayName: true, ); - final maxSats = currencyState.bitcoinCurrency.format( + final maxSat = currencyState.bitcoinCurrency.format( maxAllowedDeposit, includeDisplayName: true, ); final setUpFee = (openingFeeParams.proportional / 10000).toString(); - final liquidity = currencyState.bitcoinCurrency.format(accountState.maxInboundLiquidity); - final liquidityAboveZero = accountState.maxInboundLiquidity > 0; + final liquidity = currencyState.bitcoinCurrency.format(accountState.maxInboundLiquiditySat); + final liquidityAboveZero = accountState.maxInboundLiquiditySat > 0; final showFeeMessage = accountState.isFeesApplicable; if (!showFeeMessage) { - // Send more than {minSats} and up to {maxSats} to this address. This address can be used only once. - return texts.invoice_btc_address_channel_not_needed(minFeeFormatted, maxSats); + // Send more than {minSat} and up to {maxSat} to this address. This address can be used only once. + return texts.invoice_btc_address_channel_not_needed(minFeeFormatted, maxSat); } else if (minFeeAboveZero && liquidityAboveZero) { - // Send more than {minSats} and up to {maxSats} to this address. A setup fee of {setUpFee}% with a minimum of {minFee} + // Send more than {minSat} and up to {maxSat} to this address. A setup fee of {setUpFee}% with a minimum of {minFee} // will be applied for sending more than {liquidity}. This address can be used only once. return texts.invoice_btc_address_warning_with_min_fee_account_connected( - minSats, - maxSats, + minSat, + maxSat, setUpFee, minFeeFormatted, liquidity, ); } else if (minFeeAboveZero && !liquidityAboveZero) { - // Send more than {minSats} and up to {maxSats} to this address. A setup fee of {setUpFee}% with a minimum of {minFee} + // Send more than {minSat} and up to {maxSat} to this address. A setup fee of {setUpFee}% with a minimum of {minFee} // will be applied on the received amount. return texts.invoice_btc_address_warning_with_min_fee_account_not_connected( - minSats, - maxSats, + minSat, + maxSat, setUpFee, minFeeFormatted, ); } else if (!minFeeAboveZero && liquidityAboveZero) { - // Send more than {minSats} and up to {maxSats} to this address. A setup fee of {setUpFee}% will be applied + // Send more than {minSat} and up to {maxSat} to this address. A setup fee of {setUpFee}% will be applied // for sending more than {liquidity}. return texts.invoice_btc_address_warning_without_min_fee_account_connected( - minSats, - maxSats, + minSat, + maxSat, setUpFee, liquidity, ); } else { - // Send more than {minSats} and up to {maxSats} to this address. A setup fee of {setUpFee}% will be applied + // Send more than {minSat} and up to {maxSat} to this address. A setup fee of {setUpFee}% will be applied // on the received amount. return texts.invoice_btc_address_warning_without_min_fee_account_not_connected( - minSats, - maxSats, + minSat, + maxSat, setUpFee, ); } diff --git a/lib/routes/withdraw/redeem_onchain_funds/confirmation_page/redeem_onchain_funds_confirmation.dart b/lib/routes/withdraw/redeem_onchain_funds/confirmation_page/redeem_onchain_funds_confirmation.dart index 0370d8881..f5b125d7b 100644 --- a/lib/routes/withdraw/redeem_onchain_funds/confirmation_page/redeem_onchain_funds_confirmation.dart +++ b/lib/routes/withdraw/redeem_onchain_funds/confirmation_page/redeem_onchain_funds_confirmation.dart @@ -91,7 +91,8 @@ class _RedeemOnchainConfirmationPageState extends State().state; setState(() { affordableFees = feeOptions - .where((f) => f.isAffordable(walletBalance: account.walletBalance, amountSat: widget.amountSat)) + .where((f) => + f.isAffordable(walletBalanceSat: account.walletBalanceSat, amountSat: widget.amountSat)) .toList(); selectedFeeIndex = (affordableFees.length / 2).floor(); }); diff --git a/lib/routes/withdraw/redeem_onchain_funds/redeem_onchain_funds_page.dart b/lib/routes/withdraw/redeem_onchain_funds/redeem_onchain_funds_page.dart index 1be299a17..0ddfd65b3 100644 --- a/lib/routes/withdraw/redeem_onchain_funds/redeem_onchain_funds_page.dart +++ b/lib/routes/withdraw/redeem_onchain_funds/redeem_onchain_funds_page.dart @@ -19,10 +19,10 @@ import 'package:logging/logging.dart'; final _log = Logger("RedeemFundsPage"); class RedeemFundsPage extends StatefulWidget { - final int walletBalance; + final int walletBalanceSat; const RedeemFundsPage({ - required this.walletBalance, + required this.walletBalanceSat, super.key, }); @@ -41,7 +41,7 @@ class _RedeemFundsPageState extends State { void initState() { super.initState(); if (_withdrawMaxValue) { - _setAmount(widget.walletBalance); + _setAmount(widget.walletBalanceSat); } } @@ -85,10 +85,10 @@ class _RedeemFundsPageState extends State { withdrawMaxValue: _withdrawMaxValue, policy: WithdrawFundsPolicy( WithdrawKind.unexpected_funds, - widget.walletBalance, - widget.walletBalance, + widget.walletBalanceSat, + widget.walletBalanceSat, ), - balance: widget.walletBalance, + balanceSat: widget.walletBalanceSat, ); }, ), @@ -106,7 +106,7 @@ class _RedeemFundsPageState extends State { setState(() { _withdrawMaxValue = value; if (_withdrawMaxValue) { - _setAmount(widget.walletBalance); + _setAmount(widget.walletBalanceSat); } else { _amountController.text = ""; } @@ -130,7 +130,7 @@ class _RedeemFundsPageState extends State { FadeInRoute( builder: (_) => RedeemOnchainConfirmationPage( toAddress: _addressController.text, - amountSat: _getAmount(), + amountSat: _getAmountSat(), ), ), ); @@ -143,24 +143,24 @@ class _RedeemFundsPageState extends State { ); } - int _getAmount() { + int _getAmountSat() { final bitcoinCurrency = context.read().state.bitcoinCurrency; - int amount = 0; + int amountSat = 0; try { - amount = bitcoinCurrency.parse(_amountController.text); + amountSat = bitcoinCurrency.parse(_amountController.text); } catch (e) { - _log.warning("Failed to parse the input amount", e); + _log.warning("Failed to parse the input amountSat", e); } - return amount; + return amountSat; } - void _setAmount(int amountSats) { + void _setAmount(int amountSat) { final bitcoinCurrency = context.read().state.bitcoinCurrency; setState(() { _amountController.text = bitcoinCurrency - .format(amountSats, includeDisplayName: false, userInput: true) + .format(amountSat, includeDisplayName: false, userInput: true) .formatBySatAmountFormFieldFormatter(); }); } diff --git a/lib/routes/withdraw/reverse_swap/confirmation_page/reverse_swap_confirmation_page.dart b/lib/routes/withdraw/reverse_swap/confirmation_page/reverse_swap_confirmation_page.dart index db77959a5..f231bf310 100644 --- a/lib/routes/withdraw/reverse_swap/confirmation_page/reverse_swap_confirmation_page.dart +++ b/lib/routes/withdraw/reverse_swap/confirmation_page/reverse_swap_confirmation_page.dart @@ -93,7 +93,7 @@ class _ReverseSwapConfirmationPageState extends State().state; setState(() { affordableFees = feeOptions - .where((f) => f.isAffordable(balance: account.balance, amountSat: widget.amountSat)) + .where((f) => f.isAffordable(balanceSat: account.balanceSat, amountSat: widget.amountSat)) .toList(); selectedFeeIndex = (affordableFees.length / 2).floor(); }); diff --git a/lib/routes/withdraw/reverse_swap/reverse_swap_form.dart b/lib/routes/withdraw/reverse_swap/reverse_swap_form.dart index d703051f3..487a7350f 100644 --- a/lib/routes/withdraw/reverse_swap/reverse_swap_form.dart +++ b/lib/routes/withdraw/reverse_swap/reverse_swap_form.dart @@ -56,10 +56,10 @@ class _ReverseSwapFormState extends State { } } - void _setAmount(int amountSats) { + void _setAmount(int amountSat) { setState(() { widget.amountController.text = widget.bitcoinCurrency - .format(amountSats, includeDisplayName: false, userInput: true) + .format(amountSat, includeDisplayName: false, userInput: true) .formatBySatAmountFormFieldFormatter(); }); } @@ -84,7 +84,7 @@ class _ReverseSwapFormState extends State { bitcoinCurrency: widget.bitcoinCurrency, controller: widget.amountController, withdrawMaxValue: widget.withdrawMaxValue, - balance: widget.paymentLimits.maxSat, + balanceSat: widget.paymentLimits.maxSat, policy: WithdrawFundsPolicy( WithdrawKind.withdraw_funds, widget.paymentLimits.minSat, diff --git a/lib/routes/withdraw/reverse_swap/reverse_swap_form_page.dart b/lib/routes/withdraw/reverse_swap/reverse_swap_form_page.dart index 169fa3314..720b1a956 100644 --- a/lib/routes/withdraw/reverse_swap/reverse_swap_form_page.dart +++ b/lib/routes/withdraw/reverse_swap/reverse_swap_form_page.dart @@ -94,14 +94,14 @@ class _ReverseSwapFormPageState extends State { ); } - int _getAmount() { - int amount = 0; + int _getAmountSat() { + int amountSat = 0; try { - amount = widget.bitcoinCurrency.parse(_amountController.text); + amountSat = widget.bitcoinCurrency.parse(_amountController.text); } catch (e) { - _log.warning("Failed to parse the input amount", e); + _log.warning("Failed to parse the input amountSat", e); } - return amount; + return amountSat; } void _prepareReverseSwap() async { @@ -111,14 +111,14 @@ class _ReverseSwapFormPageState extends State { var loaderRoute = createLoaderRoute(context); navigator.push(loaderRoute); try { - int amount = _getAmount(); + int amountSat = _getAmountSat(); if (loaderRoute.isActive) { navigator.removeRoute(loaderRoute); } navigator.push( FadeInRoute( builder: (_) => ReverseSwapConfirmationPage( - amountSat: amount, + amountSat: amountSat, amountType: SwapAmountType.Receive, onchainRecipientAddress: _addressController.text, isMaxValue: _withdrawMaxValue, diff --git a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown.dart b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown.dart index 0df0516f4..c8d8a5cc4 100644 --- a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown.dart +++ b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown.dart @@ -20,9 +20,9 @@ class FeeBreakdown extends StatelessWidget { final themeData = Theme.of(context); var feeOption = this.feeOption; - int? boltzServiceFee; + int? boltzServiceFeeSat; if (feeOption is ReverseSwapFeeOption) { - boltzServiceFee = feeOption.pairInfo.totalFees - feeOption.txFeeSat; + boltzServiceFeeSat = feeOption.pairInfo.totalFees - feeOption.txFeeSat; } return Container( @@ -39,8 +39,8 @@ class FeeBreakdown extends StatelessWidget { ? feeOption.pairInfo.senderAmountSat : amountSat + feeOption.txFeeSat, ), - if (boltzServiceFee != null) ...[ - BoltzServiceFee(boltzServiceFee: boltzServiceFee), + if (boltzServiceFeeSat != null) ...[ + BoltzServiceFee(boltzServiceFeeSat: boltzServiceFeeSat), ], TransactionFee(txFeeSat: feeOption.txFeeSat), RecipientAmount( diff --git a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/boltz_service_fee.dart b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/boltz_service_fee.dart index 418d967a3..626232ea2 100644 --- a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/boltz_service_fee.dart +++ b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/boltz_service_fee.dart @@ -5,10 +5,10 @@ import 'package:c_breez/utils/min_font_size.dart'; import 'package:flutter/material.dart'; class BoltzServiceFee extends StatelessWidget { - final int boltzServiceFee; + final int boltzServiceFeeSat; const BoltzServiceFee({ - required this.boltzServiceFee, + required this.boltzServiceFeeSat, super.key, }); @@ -28,7 +28,7 @@ class BoltzServiceFee extends StatelessWidget { ), trailing: AutoSizeText( texts.reverse_swap_confirmation_boltz_fee_value( - BitcoinCurrency.SAT.format(boltzServiceFee), + BitcoinCurrency.SAT.format(boltzServiceFeeSat), ), style: TextStyle(color: themeData.colorScheme.error.withOpacity(0.4)), maxLines: 1, diff --git a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/recipient_amount.dart b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/recipient_amount.dart index deaf307c8..5de5ea403 100644 --- a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/recipient_amount.dart +++ b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/recipient_amount.dart @@ -39,7 +39,7 @@ class RecipientAmount extends StatelessWidget { ) : texts.sweep_all_coins_amount_with_fiat( BitcoinCurrency.SAT.format(amountSat), - fiatConversion.format(amountSat), + fiatConversion.formatSat(amountSat), ), style: TextStyle(color: themeData.colorScheme.error), maxLines: 1, diff --git a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/sender_amount.dart b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/sender_amount.dart index 1ee5b4fab..ab36029fd 100644 --- a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/sender_amount.dart +++ b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_breakdown_widgets/sender_amount.dart @@ -39,7 +39,7 @@ class SenderAmount extends StatelessWidget { ) : texts.sweep_all_coins_amount_with_fiat( BitcoinCurrency.SAT.format(amountSat), - fiatConversion.format(amountSat), + fiatConversion.formatSat(amountSat), ), style: TextStyle(color: themeData.colorScheme.error), maxLines: 1, diff --git a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_chooser_header.dart b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_chooser_header.dart index 9f31c5dc0..2660170c2 100644 --- a/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_chooser_header.dart +++ b/lib/routes/withdraw/widgets/fee_chooser/widgets/fee_chooser_header.dart @@ -44,8 +44,8 @@ class _FeeChooserHeaderState extends State { index: index, text: feeOption.getDisplayName(texts), isAffordable: feeOption.isAffordable( - balance: account.balance, - walletBalance: account.walletBalance, + balanceSat: account.balanceSat, + walletBalanceSat: account.walletBalanceSat, amountSat: widget.amountSat, ), isSelected: widget.selectedFeeIndex == index, diff --git a/lib/routes/withdraw/widgets/withdraw_funds_amount_text_form_field.dart b/lib/routes/withdraw/widgets/withdraw_funds_amount_text_form_field.dart index f1ee569a3..0cc8169cf 100644 --- a/lib/routes/withdraw/widgets/withdraw_funds_amount_text_form_field.dart +++ b/lib/routes/withdraw/widgets/withdraw_funds_amount_text_form_field.dart @@ -18,29 +18,29 @@ class WithdrawFundsAmountTextFormField extends AmountFormField { required TextEditingController super.controller, required bool withdrawMaxValue, required WithdrawFundsPolicy policy, - required int balance, + required int balanceSat, }) : super( texts: context.texts(), readOnly: policy.withdrawKind == WithdrawKind.unexpected_funds || withdrawMaxValue, - validatorFn: (amount) { - _log.info("Validator called for $amount"); + validatorFn: (paymentAmountSat) { + _log.info("Validator called for $paymentAmountSat"); return PaymentValidator( currency: bitcoinCurrency, texts: context.texts(), channelCreationPossible: context.read().state?.isChannelOpeningAvailable ?? false, - validatePayment: (amount, outgoing, channelCreationPossible, {channelMinimumFee}) { - _log.info("Validating $amount $policy"); - if (amount < policy.minValue) { + validatePayment: (amountSat, outgoing, channelCreationPossible, {channelMinimumFeeSat}) { + _log.info("Validating $amountSat $policy"); + if (amountSat < policy.minValue) { throw PaymentBelowLimitError(policy.minValue); } - if (amount > policy.maxValue) { + if (amountSat > policy.maxValue) { throw PaymentExceededLimitError(policy.maxValue); } - if (amount > balance) { + if (amountSat > balanceSat) { throw const InsufficientLocalBalanceError(); } }, - ).validateOutgoing(amount); + ).validateOutgoing(paymentAmountSat); }, ); } diff --git a/lib/routes/withdraw/widgets/withdraw_funds_available_btc.dart b/lib/routes/withdraw/widgets/withdraw_funds_available_btc.dart index 932cd2285..0b609a0c0 100644 --- a/lib/routes/withdraw/widgets/withdraw_funds_available_btc.dart +++ b/lib/routes/withdraw/widgets/withdraw_funds_available_btc.dart @@ -28,7 +28,7 @@ class WithdrawFundsAvailableBtc extends StatelessWidget { child: BlocBuilder( builder: (context, currencyState) { return Text( - currencyState.bitcoinCurrency.format(account.balance), + currencyState.bitcoinCurrency.format(account.balanceSat), style: theme.textStyle, ); }, diff --git a/lib/user_app.dart b/lib/user_app.dart index e102a880e..6ead88e98 100644 --- a/lib/user_app.dart +++ b/lib/user_app.dart @@ -190,7 +190,7 @@ class UserApp extends StatelessWidget { case '/unexpected_funds': return FadeInRoute( builder: (_) => RedeemFundsPage( - walletBalance: settings.arguments as int, + walletBalanceSat: settings.arguments as int, ), settings: settings, ); diff --git a/lib/utils/currency_formatter.dart b/lib/utils/currency_formatter.dart index 2d5723f58..8236a9104 100644 --- a/lib/utils/currency_formatter.dart +++ b/lib/utils/currency_formatter.dart @@ -33,15 +33,18 @@ class CurrencyFormatter { class BitcoinCurrencyFormatter { static final formatter = CurrencyFormatter().formatter; - String format(satoshies, BitcoinCurrency currency, - {bool addCurrencySuffix = true, - bool addCurrencySymbol = false, - removeTrailingZeros = false, - userInput = false}) { - String formattedAmount = formatter.format(satoshies); + String format( + amountSat, + BitcoinCurrency currency, { + bool addCurrencySuffix = true, + bool addCurrencySymbol = false, + removeTrailingZeros = false, + userInput = false, + }) { + String formattedAmount = formatter.format(amountSat); switch (currency) { case BitcoinCurrency.BTC: - double amountInBTC = (satoshies.toInt() / 100000000); + double amountInBTC = (amountSat.toInt() / 100000000); formattedAmount = amountInBTC.toStringAsFixed(8); if (removeTrailingZeros) { if (amountInBTC.truncateToDouble() == amountInBTC) { @@ -53,7 +56,7 @@ class BitcoinCurrencyFormatter { } break; case BitcoinCurrency.SAT: - formattedAmount = formatter.format(satoshies); + formattedAmount = formatter.format(amountSat); break; } if (addCurrencySymbol) { diff --git a/lib/utils/fiat_conversion.dart b/lib/utils/fiat_conversion.dart index e3dd5d2c8..c5024d4d2 100644 --- a/lib/utils/fiat_conversion.dart +++ b/lib/utils/fiat_conversion.dart @@ -37,8 +37,8 @@ class FiatConversion { return satoshies.toDouble() / 100000000 * exchangeRate; } - String format(int amount) { - double fiatValue = satToFiat(amount); + String formatSat(int amountSat) { + double fiatValue = satToFiat(amountSat); return formatFiat(fiatValue); } diff --git a/lib/utils/payment_validator.dart b/lib/utils/payment_validator.dart index f13cb8a4b..355991903 100644 --- a/lib/utils/payment_validator.dart +++ b/lib/utils/payment_validator.dart @@ -7,37 +7,42 @@ import 'package:logging/logging.dart'; final _log = Logger("PaymentValidator"); class PaymentValidator { + final BreezTranslations texts; final BitcoinCurrency currency; final void Function( - int amount, + int amountSat, bool outgoing, bool channelCreationPossible, { - int? channelMinimumFee, + int? channelMinimumFeeSat, }) validatePayment; final bool channelCreationPossible; - final int? channelMinimumFee; - final BreezTranslations texts; + final int? channelMinimumFeeSat; const PaymentValidator({ - required this.validatePayment, + required this.texts, required this.currency, + required this.validatePayment, required this.channelCreationPossible, - this.channelMinimumFee, - required this.texts, + this.channelMinimumFeeSat, }); - String? validateIncoming(int amount) { - return _validate(amount, false); + String? validateIncoming(int amountSat) { + return _validate(amountSat, false); } - String? validateOutgoing(int amount) { - return _validate(amount, true); + String? validateOutgoing(int amountSat) { + return _validate(amountSat, true); } - String? _validate(int amount, bool outgoing) { - _log.info("Validating for $amount and $outgoing"); + String? _validate(int amountSat, bool outgoing) { + _log.info("Validating for $amountSat and $outgoing"); try { - validatePayment(amount, outgoing, channelCreationPossible, channelMinimumFee: channelMinimumFee); + validatePayment( + amountSat, + outgoing, + channelCreationPossible, + channelMinimumFeeSat: channelMinimumFeeSat, + ); } on PaymentExceededLimitError catch (e) { _log.info("Got PaymentExceededLimitError", e); return texts.invoice_payment_validator_error_payment_exceeded_limit( @@ -51,20 +56,20 @@ class PaymentValidator { } on PaymentBelowReserveError catch (e) { _log.info("Got PaymentBelowReserveError", e); return texts.invoice_payment_validator_error_payment_below_limit( - currency.format(e.reserveAmount), + currency.format(e.reserveAmountSat), ); - } on PaymentExceedLiquidityError catch (e) { + } on PaymentExceededLiquidityError catch (e) { return "Insufficient inbound liquidity (${currency.format(e.limitSat)})"; } on InsufficientLocalBalanceError { return texts.invoice_payment_validator_error_insufficient_local_balance; } on PaymentBelowSetupFeesError catch (e) { _log.info("Got PaymentBelowSetupFeesError", e); return texts.invoice_payment_validator_error_payment_below_setup_fees_error( - currency.format(e.setupFees), + currency.format(e.setupFeesSat), ); - } on PaymentExcededLiqudityChannelCreationNotPossibleError catch (e) { + } on PaymentExceededLiquidityChannelCreationNotPossibleError catch (e) { return texts.lnurl_fetch_invoice_error_max(currency.format(e.limitSat)); - } on NoChannelCreationZeroLiqudityError { + } on NoChannelCreationZeroLiquidityError { return texts.lsp_error_cannot_open_channel; } catch (e) { _log.info("Got Generic error", e); diff --git a/lib/widgets/amount_form_field/amount_form_field.dart b/lib/widgets/amount_form_field/amount_form_field.dart index 9d6b638b2..0a197824c 100644 --- a/lib/widgets/amount_form_field/amount_form_field.dart +++ b/lib/widgets/amount_form_field/amount_form_field.dart @@ -13,7 +13,7 @@ import 'sat_amount_form_field_formatter.dart'; class AmountFormField extends TextFormField { final FiatConversion? fiatConversion; final BitcoinCurrency bitcoinCurrency; - final String? Function(int amount) validatorFn; + final String? Function(int amountSat) validatorFn; final BreezTranslations texts; AmountFormField({ @@ -23,7 +23,7 @@ class AmountFormField extends TextFormField { required this.texts, required BuildContext context, Color? iconColor, - Function(String amount)? returnFN, + Function(String amountSat)? returnFN, super.controller, Key? key, String? initialValue, diff --git a/lib/widgets/amount_form_field/currency_converter_dialog.dart b/lib/widgets/amount_form_field/currency_converter_dialog.dart index ef89a0899..661c6c6c1 100644 --- a/lib/widgets/amount_form_field/currency_converter_dialog.dart +++ b/lib/widgets/amount_form_field/currency_converter_dialog.dart @@ -14,7 +14,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; class CurrencyConverterDialog extends StatefulWidget { final Function(String string) _onConvert; - final String? Function(int amount) validatorFn; + final String? Function(int amountSat) validatorFn; final CurrencyBloc _currencyBloc; const CurrencyConverterDialog( @@ -290,14 +290,14 @@ class CurrencyConverterDialogState extends State } String _contentMessage(CurrencyState currencyState) { - final amount = _fiatAmountController.text.isNotEmpty + final btcAmount = _fiatAmountController.text.isNotEmpty ? currencyState.bitcoinCurrency.format( _convertedSatoshies(currencyState), includeDisplayName: false, ) : 0; final symbol = currencyState.bitcoinCurrency.tickerSymbol; - return "$amount $symbol"; + return "$btcAmount $symbol"; } void _updateExchangeLabel(double exchangeRate) { diff --git a/lib/widgets/payment_dialogs/payment_confirmation_dialog.dart b/lib/widgets/payment_dialogs/payment_confirmation_dialog.dart index 5a12f783b..fab12c60d 100644 --- a/lib/widgets/payment_dialogs/payment_confirmation_dialog.dart +++ b/lib/widgets/payment_dialogs/payment_confirmation_dialog.dart @@ -4,15 +4,15 @@ import 'package:flutter/material.dart'; class PaymentConfirmationDialog extends StatelessWidget { final String bolt11; - final int _amountToPay; + final int _amountToPaySat; final String _amountToPayStr; final Function() _onCancel; - final Function(String bolt11, int amount) _onPaymentApproved; + final Function(String bolt11, int amountSat) _onPaymentApproved; final double minHeight; const PaymentConfirmationDialog( this.bolt11, - this._amountToPay, + this._amountToPaySat, this._amountToPayStr, this._onCancel, this._onPaymentApproved, @@ -139,7 +139,7 @@ class PaymentConfirmationDialog extends StatelessWidget { onPressed: () { _onPaymentApproved( bolt11, - _amountToPay, + _amountToPaySat, ); }, ), diff --git a/lib/widgets/payment_dialogs/payment_request_dialog.dart b/lib/widgets/payment_dialogs/payment_request_dialog.dart index ca18e11b2..53fcb7970 100644 --- a/lib/widgets/payment_dialogs/payment_request_dialog.dart +++ b/lib/widgets/payment_dialogs/payment_request_dialog.dart @@ -34,7 +34,7 @@ class PaymentRequestDialogState extends State { late AccountBloc accountBloc; PaymentRequestState? _state; String? _amountToPayStr; - int? _amountToPay; + int? _amountToPaySat; ModalRoute? _currentRoute; @@ -80,18 +80,18 @@ class PaymentRequestDialogState extends State { minHeight: minHeight, paymentFunc: () => accountBloc.sendPayment( widget.invoice.bolt11, - widget.invoice.amountMsat == 0 ? _amountToPay! * 1000 : null, + widget.invoice.amountMsat == 0 ? _amountToPaySat! * 1000 : null, ), onStateChange: (state) => _onStateChange(state), ); } else if (_state == PaymentRequestState.WAITING_FOR_CONFIRMATION) { return PaymentConfirmationDialog( widget.invoice.bolt11, - _amountToPay!, + _amountToPaySat!, _amountToPayStr!, () => _onStateChange(PaymentRequestState.USER_CANCELLED), - (bolt11, amount) => setState(() { - _amountToPay = amount; + (bolt11, amountSat) => setState(() { + _amountToPaySat = amountSat; _onStateChange(PaymentRequestState.PROCESSING_PAYMENT); }), minHeight, @@ -101,11 +101,11 @@ class PaymentRequestDialogState extends State { widget.invoice, () => _onStateChange(PaymentRequestState.USER_CANCELLED), () => _onStateChange(PaymentRequestState.WAITING_FOR_CONFIRMATION), - (bolt11, amount) { - _amountToPay = amount; + (bolt11, amountSat) { + _amountToPaySat = amountSat; _onStateChange(PaymentRequestState.PROCESSING_PAYMENT); }, - (map) => _setAmountToPay(map), + (map) => _setAmountToPaySat(map), minHeight, ); } @@ -126,8 +126,8 @@ class PaymentRequestDialogState extends State { }); } - void _setAmountToPay(Map map) { - _amountToPay = map["_amountToPay"]; + void _setAmountToPaySat(Map map) { + _amountToPaySat = map["_amountToPaySat"]; _amountToPayStr = map["_amountToPayStr"]; } } diff --git a/lib/widgets/payment_dialogs/payment_request_info_dialog.dart b/lib/widgets/payment_dialogs/payment_request_info_dialog.dart index 29c555c5c..a693ee06b 100644 --- a/lib/widgets/payment_dialogs/payment_request_info_dialog.dart +++ b/lib/widgets/payment_dialogs/payment_request_info_dialog.dart @@ -20,7 +20,7 @@ class PaymentRequestInfoDialog extends StatefulWidget { final Invoice invoice; final Function() _onCancel; final Function() _onWaitingConfirmation; - final Function(String bot11, int amount) _onPaymentApproved; + final Function(String bot11, int amountSat) _onPaymentApproved; final Function(Map map) _setAmountToPay; final double minHeight; @@ -214,7 +214,7 @@ class PaymentRequestInfoDialogState extends State { ), child: Text( _showFiatCurrency && fiatConversion != null - ? fiatConversion.format(widget.invoice.amountMsat ~/ 1000) + ? fiatConversion.formatSat(widget.invoice.amountMsat ~/ 1000) : BitcoinCurrency.fromTickerSymbol(currencyState.bitcoinTicker) .format(widget.invoice.amountMsat ~/ 1000), style: themeData.primaryTextTheme.headlineSmall, @@ -259,7 +259,7 @@ class PaymentRequestInfoDialogState extends State { channelCreationPossible: context.read().state?.isChannelOpeningAvailable ?? false, texts: context.texts(), ).validateOutgoing( - amountToPay(currencyState), + _amountToPaySat(currencyState), ); if (widget.invoice.amountMsat == 0 || validationError == null || validationError.isEmpty) { return null; @@ -295,30 +295,32 @@ class PaymentRequestInfoDialogState extends State { ) ]; - int toPay = amountToPay(currency); - if (toPay > 0 && accState.maxAllowedToPay >= toPay) { - actions.add(SimpleDialogOption( - onPressed: (() async { - if (widget.invoice.amountMsat > 0 || _formKey.currentState!.validate()) { - if (widget.invoice.amountMsat == 0) { - _amountToPayMap["_amountToPay"] = toPay; - _amountToPayMap["_amountToPayStr"] = - BitcoinCurrency.fromTickerSymbol(currency.bitcoinTicker).format(amountToPay(currency)); - widget._setAmountToPay(_amountToPayMap); - widget._onWaitingConfirmation(); - } else { - widget._onPaymentApproved( - widget.invoice.bolt11, - amountToPay(currency), - ); + int toPaySat = _amountToPaySat(currency); + if (toPaySat > 0 && accState.maxAllowedToPaySat >= toPaySat) { + actions.add( + SimpleDialogOption( + onPressed: (() async { + if (widget.invoice.amountMsat > 0 || _formKey.currentState!.validate()) { + if (widget.invoice.amountMsat == 0) { + _amountToPayMap["_amountToPaySat"] = toPaySat; + _amountToPayMap["_amountToPayStr"] = BitcoinCurrency.fromTickerSymbol(currency.bitcoinTicker) + .format(_amountToPaySat(currency)); + widget._setAmountToPay(_amountToPayMap); + widget._onWaitingConfirmation(); + } else { + widget._onPaymentApproved( + widget.invoice.bolt11, + _amountToPaySat(currency), + ); + } } - } - }), - child: Text( - texts.payment_request_dialog_action_approve, - style: themeData.primaryTextTheme.labelLarge, + }), + child: Text( + texts.payment_request_dialog_action_approve, + style: themeData.primaryTextTheme.labelLarge, + ), ), - )); + ); } return Theme( data: themeData.copyWith( @@ -336,13 +338,13 @@ class PaymentRequestInfoDialogState extends State { ); } - int amountToPay(CurrencyState acc) { - int amount = widget.invoice.amountMsat ~/ 1000; - if (amount == 0) { + int _amountToPaySat(CurrencyState acc) { + int amountSat = widget.invoice.amountMsat ~/ 1000; + if (amountSat == 0) { try { - amount = BitcoinCurrency.fromTickerSymbol(acc.bitcoinTicker).parse(_invoiceAmountController.text); + amountSat = BitcoinCurrency.fromTickerSymbol(acc.bitcoinTicker).parse(_invoiceAmountController.text); } catch (_) {} } - return amount; + return amountSat; } } diff --git a/test/bloc/account/account_bloc_test.dart b/test/bloc/account/account_bloc_test.dart index f4ebef60b..b63dbe7f7 100644 --- a/test/bloc/account/account_bloc_test.dart +++ b/test/bloc/account/account_bloc_test.dart @@ -43,14 +43,13 @@ void main() { var accountState = accBloc.state; expect(accountState.blockheight, greaterThan(1)); expect(accountState.id?.length, equals(66)); - expect(accountState.balance, 0); - expect(accountState.walletBalance, 0); - expect(accountState.maxAllowedToPay, 0); - expect(accountState.maxAllowedToReceive, 0); - expect(accountState.maxPaymentAmount, 4294967); - expect(accountState.maxChanReserve, 0); - expect(accountState.maxInboundLiquidity, 0); - expect(accountState.onChainFeeRate, 0); + expect(accountState.balanceSat, 0); + expect(accountState.walletBalanceSat, 0); + expect(accountState.maxAllowedToPaySat, 0); + expect(accountState.maxAllowedToReceiveSat, 0); + expect(accountState.maxPaymentAmountSat, 4294967); + expect(accountState.maxChanReserveSat, 0); + expect(accountState.maxInboundLiquiditySat, 0); expect(accountState.payments.length, 0); expect(accountState.verificationStatus, VerificationStatus.VERIFIED); });