diff --git a/lib/receive/bloc/state.dart b/lib/receive/bloc/state.dart index 0481ba97..a2a8d3fd 100644 --- a/lib/receive/bloc/state.dart +++ b/lib/receive/bloc/state.dart @@ -1,6 +1,7 @@ import 'package:bb_mobile/_model/address.dart'; import 'package:bb_mobile/_model/transaction.dart'; import 'package:bb_mobile/_model/wallet.dart'; +import 'package:bb_mobile/_pkg/consts/configs.dart'; import 'package:bb_mobile/wallet/bloc/wallet_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; @@ -33,6 +34,20 @@ class ReceiveState with _$ReceiveState { }) = _ReceiveState; const ReceiveState._(); + String getAddressWithAmountAndLabel(double amount, bool isLiquid, {SwapTx? swapTx}) { + final String address = getQRStr(swapTx: swapTx); + + String finalAddress = ''; + if (paymentNetwork == PaymentNetwork.lightning || (amount == 0 && description.isEmpty)) { + finalAddress = address; + } else { + finalAddress = isLiquid + ? 'liquidnetwork:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}&assetid=$liquidAssetId' + : 'bitcoin:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}'; + } + return finalAddress; + } + String getQRStr({SwapTx? swapTx}) { if (paymentNetwork == PaymentNetwork.lightning) { if (swapTx == null) return ''; @@ -45,8 +60,7 @@ class ReceiveState with _$ReceiveState { final btcAmt = (savedInvoiceAmount / 100000000).toStringAsFixed(8); var invoice = 'bitcoin:' + defaultAddress!.address + '?amount=' + btcAmt; - if (savedDescription.isNotEmpty) - invoice = invoice + '&label=' + savedDescription; + if (savedDescription.isNotEmpty) invoice = invoice + '&label=' + savedDescription; return invoice; } @@ -59,29 +73,24 @@ class ReceiveState with _$ReceiveState { return defaultAddress?.address ?? ''; } - bool showNewRequestButton() => - savedDescription.isEmpty && savedInvoiceAmount == 0; + bool showNewRequestButton() => savedDescription.isEmpty && savedInvoiceAmount == 0; bool isSupported() { - if (paymentNetwork == PaymentNetwork.bitcoin && - walletBloc!.state.wallet?.baseWalletType == BaseWalletType.Liquid) + if (paymentNetwork == PaymentNetwork.bitcoin && walletBloc!.state.wallet?.baseWalletType == BaseWalletType.Liquid) return false; - if (paymentNetwork == PaymentNetwork.liquid && - walletBloc!.state.wallet?.baseWalletType == BaseWalletType.Bitcoin) + if (paymentNetwork == PaymentNetwork.liquid && walletBloc!.state.wallet?.baseWalletType == BaseWalletType.Bitcoin) return false; return true; } bool showQR(SwapTx? swapTx) { return (swapTx != null && paymentNetwork == PaymentNetwork.lightning) || - (paymentNetwork == PaymentNetwork.bitcoin || - paymentNetwork == PaymentNetwork.liquid); + (paymentNetwork == PaymentNetwork.bitcoin || paymentNetwork == PaymentNetwork.liquid); } bool isLn() => paymentNetwork == PaymentNetwork.lightning; - bool checkIfMainWalletSelected() => - walletBloc?.state.wallet?.mainWallet ?? false; + bool checkIfMainWalletSelected() => walletBloc?.state.wallet?.mainWallet ?? false; // bool _swapTxIsNotNull() => swapBloc.state.swapTx != null; diff --git a/lib/receive/receive_page.dart b/lib/receive/receive_page.dart index e786e752..67c8570e 100644 --- a/lib/receive/receive_page.dart +++ b/lib/receive/receive_page.dart @@ -71,8 +71,7 @@ class _ReceivePageState extends State { ); final network = context.read().state.getBBNetwork(); - final walletBloc = widget.walletBloc ?? - context.read().state.getMainInstantWallet(network); + final walletBloc = widget.walletBloc ?? context.read().state.getMainInstantWallet(network); if (walletBloc!.state.wallet!.isLiquid()) { _receiveCubit.updateWalletType( @@ -122,34 +121,25 @@ class _Screen extends StatelessWidget { @override Widget build(BuildContext context) { final swapTx = context.select((SwapCubit x) => x.state.swapTx); - final isSupported = - context.select((ReceiveCubit x) => x.state.isSupported()); + final isSupported = context.select((ReceiveCubit x) => x.state.isSupported()); final showQR = context.select((ReceiveCubit x) => x.state.showQR(swapTx)); - final watchOnly = - context.select((WalletBloc x) => x.state.wallet!.watchOnly()); - final mainWallet = - context.select((ReceiveCubit x) => x.state.checkIfMainWalletSelected()); + final watchOnly = context.select((WalletBloc x) => x.state.wallet!.watchOnly()); + final mainWallet = context.select((ReceiveCubit x) => x.state.checkIfMainWalletSelected()); final walletIsLiquid = context.select( (WalletBloc x) => x.state.wallet!.baseWalletType == BaseWalletType.Liquid, ); final showWarning = context.select((SwapCubit x) => x.state.showWarning()); - final removeWarning = - context.select((SettingsCubit x) => x.state.removeSwapWarnings); + final removeWarning = context.select((SettingsCubit x) => x.state.removeSwapWarnings); - final paymentNetwork = - context.select((ReceiveCubit x) => x.state.paymentNetwork); - final formSubmitted = - context.select((ReceiveCubit x) => x.state.receiveFormSubmitted); - final shouldShowForm = paymentNetwork == PaymentNetwork.bitcoin || - paymentNetwork == PaymentNetwork.liquid; + final paymentNetwork = context.select((ReceiveCubit x) => x.state.paymentNetwork); + final formSubmitted = context.select((ReceiveCubit x) => x.state.receiveFormSubmitted); + final shouldShowForm = paymentNetwork == PaymentNetwork.bitcoin || paymentNetwork == PaymentNetwork.liquid; final description = context.select((ReceiveCubit _) => _.state.description); - final shouldShownDescription = - (paymentNetwork == PaymentNetwork.lightning && - description.isNotEmpty) || - (paymentNetwork != PaymentNetwork.lightning && formSubmitted); + final shouldShownDescription = (paymentNetwork == PaymentNetwork.lightning && description.isNotEmpty) || + (paymentNetwork != PaymentNetwork.lightning && formSubmitted); return SingleChildScrollView( child: Padding( @@ -180,8 +170,7 @@ class _Screen extends StatelessWidget { const ReceiveAddress(), const Gap(8), if (shouldShowForm) const BitcoinReceiveForm(), - if (paymentNetwork == PaymentNetwork.lightning || formSubmitted) - const RequestedAmount(), + if (paymentNetwork == PaymentNetwork.lightning || formSubmitted) const RequestedAmount(), if (shouldShownDescription) const Gap(8), if (shouldShownDescription) const PaymentDescription(), const Gap(16), @@ -209,10 +198,8 @@ class ReceiveWalletsDropDown extends StatelessWidget { @override Widget build(BuildContext context) { final network = context.select((NetworkCubit _) => _.state.getBBNetwork()); - final walletBlocs = context - .select((HomeCubit _) => _.state.walletBlocsFromNetwork(network)); - final selectedWalletBloc = - context.select((ReceiveCubit _) => _.state.walletBloc); + final walletBlocs = context.select((HomeCubit _) => _.state.walletBlocsFromNetwork(network)); + final selectedWalletBloc = context.select((ReceiveCubit _) => _.state.walletBloc); final walletBloc = selectedWalletBloc ?? walletBlocs.first; @@ -220,8 +207,7 @@ class ReceiveWalletsDropDown extends StatelessWidget { items: { for (final wallet in walletBlocs) wallet: ( - label: wallet.state.wallet!.name ?? - wallet.state.wallet!.sourceFingerprint, + label: wallet.state.wallet!.name ?? wallet.state.wallet!.sourceFingerprint, enabled: true, ), }, @@ -240,8 +226,7 @@ class SelectWalletType extends StatelessWidget { @override Widget build(BuildContext context) { // final isTestnet = context.select((NetworkCubit _) => _.state.testnet); - final paymentNetwork = - context.select((ReceiveCubit x) => x.state.paymentNetwork); + final paymentNetwork = context.select((ReceiveCubit x) => x.state.paymentNetwork); // if (!isTestnet) return const SizedBox.shrink(); @@ -253,8 +238,7 @@ class SelectWalletType extends StatelessWidget { PaymentNetwork.liquid: 'Liquid', }, onChanged: (value) { - if (paymentNetwork == PaymentNetwork.lightning) - context.read().clearSwapTx(); + if (paymentNetwork == PaymentNetwork.lightning) context.read().clearSwapTx(); context.read().reset(); context.read().updateAmountDirect(0); @@ -353,10 +337,8 @@ class _Warnings extends StatelessWidget { final swapTx = context.select((SwapCubit x) => x.state.swapTx); if (swapTx == null) return const SizedBox.shrink(); - final errLowAmt = - context.select((SwapCubit x) => x.state.swapTx!.smallAmt()); - final errHighFees = - context.select((SwapCubit x) => x.state.swapTx!.highFees()); + final errLowAmt = context.select((SwapCubit x) => x.state.swapTx!.smallAmt()); + final errHighFees = context.select((SwapCubit x) => x.state.swapTx!.highFees()); return WarningContainer( children: [ @@ -404,8 +386,7 @@ class _RemoveWarningMessage extends StatelessWidget { @override Widget build(BuildContext context) { - final removeWarning = - context.select((SettingsCubit x) => x.state.removeSwapWarnings); + final removeWarning = context.select((SettingsCubit x) => x.state.removeSwapWarnings); return Row( children: [ @@ -414,8 +395,7 @@ class _RemoveWarningMessage extends StatelessWidget { visualDensity: VisualDensity.compact, value: removeWarning, onChanged: (checked) { - if (checked != null) - context.read().changeSwapWarnings(checked); + if (checked != null) context.read().changeSwapWarnings(checked); }, side: BorderSide(width: 2, color: context.colour.surface), // fillColor: context.colour.surface, @@ -445,10 +425,8 @@ class WalletActions extends StatelessWidget { final show = context.select((ReceiveCubit _) => _.state.showQR(swap)); if (!show) return const SizedBox.shrink(); - final showRequestButton = - context.select((ReceiveCubit x) => x.state.showNewRequestButton()); - final errLoadingAddress = - context.select((ReceiveCubit x) => x.state.errLoadingAddress); + final showRequestButton = context.select((ReceiveCubit x) => x.state.showNewRequestButton()); + final errLoadingAddress = context.select((ReceiveCubit x) => x.state.errLoadingAddress); return Column( children: [ @@ -472,10 +450,8 @@ class WalletActions extends StatelessWidget { leftSvgAsset: 'assets/new-address.svg', onPressed: () { context.read().updateAmountDirect(0); - final paymentNetwork = - context.read().state.paymentNetwork; - if (paymentNetwork == PaymentNetwork.lightning) - context.read().clearSwapTx(); + final paymentNetwork = context.read().state.paymentNetwork; + if (paymentNetwork == PaymentNetwork.lightning) context.read().clearSwapTx(); context.read().generateNewAddress(); }, @@ -493,8 +469,7 @@ class CreateLightningInvoice extends StatelessWidget { Widget build(BuildContext context) { final description = context.select((ReceiveCubit _) => _.state.description); final err = context.select((SwapCubit _) => _.state.errCreatingSwapInv); - final creatingInv = - context.select((SwapCubit _) => _.state.generatingSwapInv); + final creatingInv = context.select((SwapCubit _) => _.state.generatingSwapInv); final allFees = context.select((SwapCubit x) => x.state.allFees); final amount = context.select((CurrencyCubit x) => x.state.amount); @@ -547,10 +522,8 @@ class CreateLightningInvoice extends StatelessWidget { loadingText: 'Creating Invoice', onPressed: () async { final amt = context.read().state.amount; - final wallet = - context.read().state.walletBloc!.state.wallet!; - final walletIsLiquid = - wallet.baseWalletType == BaseWalletType.Liquid; + final wallet = context.read().state.walletBloc!.state.wallet!; + final walletIsLiquid = wallet.baseWalletType == BaseWalletType.Liquid; final label = context.read().state.description; final isTestnet = context.read().state.testnet; final networkUrl = !walletIsLiquid @@ -634,8 +607,7 @@ class SwapFeesDetails extends StatelessWidget { final totalFees = swapTx.totalFees() ?? 0; final fees = context.select( - (CurrencyCubit x) => - x.state.getAmountInUnits(totalFees, removeText: true), + (CurrencyCubit x) => x.state.getAmountInUnits(totalFees, removeText: true), ); final units = context.select( (CurrencyCubit cubit) => cubit.state.getUnitString(), @@ -685,29 +657,23 @@ class ReceiveQR extends StatelessWidget { @override Widget build(BuildContext context) { - final paymentNetwork = - context.select((ReceiveCubit x) => x.state.paymentNetwork); + final paymentNetwork = context.select((ReceiveCubit x) => x.state.paymentNetwork); final swapTx = context.select((SwapCubit x) => x.state.swapTx); - final address = - context.select((ReceiveCubit x) => x.state.getQRStr(swapTx: swapTx)); - final amount = - context.select((CurrencyCubit x) => x.state.amount / 100000000.0); + final address = context.select((ReceiveCubit x) => x.state.getQRStr(swapTx: swapTx)); + final amount = context.select((CurrencyCubit x) => x.state.amount / 100000000.0); final description = context.select((ReceiveCubit x) => x.state.description); final isLiquid = context.select( (ReceiveCubit x) => x.state.walletBloc?.state.wallet?.isLiquid() ?? false, ); + final bip21Address = context.select( + (ReceiveCubit x) => x.state.getAddressWithAmountAndLabel( + amount, + isLiquid, + swapTx: swapTx, + ), + ); - String finalAddress = ''; - if (paymentNetwork == PaymentNetwork.lightning || - (amount == 0 && description.isEmpty)) { - finalAddress = address; - } else { - // finalAddress = isLiquid - // ? 'liquidnetwork:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}&assetid=$liquidAssetId' - // : 'bitcoin:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}'; - } - - return ReceiveQRDisplay(address: finalAddress); + return ReceiveQRDisplay(address: bip21Address); } } @@ -721,8 +687,7 @@ class ReceiveQRDisplay extends StatelessWidget { return Center( child: GestureDetector( onTap: () async { - if (locator.isRegistered()) - await locator().copy(address); + if (locator.isRegistered()) await locator().copy(address); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Copied to clipboard')), @@ -750,8 +715,7 @@ class ReceiveAddress extends StatelessWidget { @override Widget build(BuildContext context) { final swapTx = context.select((SwapCubit x) => x.state.swapTx); - final addressQr = - context.select((ReceiveCubit x) => x.state.getQRStr(swapTx: swapTx)); + final addressQr = context.select((ReceiveCubit x) => x.state.getQRStr(swapTx: swapTx)); return ReceiveDisplayAddress(addressQr: addressQr); } @@ -762,16 +726,12 @@ class RequestedAmount extends StatelessWidget { @override Widget build(BuildContext context) { - final payNetwork = - context.select((ReceiveCubit x) => x.state.paymentNetwork); + final payNetwork = context.select((ReceiveCubit x) => x.state.paymentNetwork); final swapTx = context.select((SwapCubit x) => x.state.swapTx); final amount = context.select((CurrencyCubit x) => x.state.amount); - final requestedAmount = payNetwork == PaymentNetwork.lightning - ? (swapTx?.outAmount ?? 0) - : amount; + final requestedAmount = payNetwork == PaymentNetwork.lightning ? (swapTx?.outAmount ?? 0) : amount; final requestedAmountStr = context.select( - (CurrencyCubit x) => - x.state.getAmountInUnits(requestedAmount, removeText: true), + (CurrencyCubit x) => x.state.getAmountInUnits(requestedAmount, removeText: true), ); final units = context.select( (CurrencyCubit cubit) => cubit.state.getUnitString(), @@ -832,8 +792,7 @@ class _ReceiveDisplayAddressState extends State { // ? widget.addressQr // : widget.addressQr.substring(0, 10) + ' ... ' + widget.addressQr.substring(widget.addressQr.length - 5) // : widget.addressQr; - final paymentNetwork = - context.select((ReceiveCubit x) => x.state.paymentNetwork); + final paymentNetwork = context.select((ReceiveCubit x) => x.state.paymentNetwork); String receiveAddressLabel = 'Payment invoice'; if (paymentNetwork == PaymentNetwork.bitcoin) { @@ -844,22 +803,19 @@ class _ReceiveDisplayAddressState extends State { final address = widget.addressQr; - final amount = - context.select((CurrencyCubit x) => x.state.amount / 100000000.0); + final swapTx = context.select((SwapCubit x) => x.state.swapTx); + final amount = context.select((CurrencyCubit x) => x.state.amount / 100000000.0); final description = context.select((ReceiveCubit x) => x.state.description); final isLiquid = context.select( (ReceiveCubit x) => x.state.walletBloc?.state.wallet?.isLiquid() ?? false, ); - - String finalAddress = ''; - if (paymentNetwork == PaymentNetwork.lightning || - (amount == 0 && description.isEmpty)) { - finalAddress = address; - } else { - // finalAddress = isLiquid - // ? 'liquidnetwork:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}&assetid=$liquidAssetId' - // : 'bitcoin:$address&amount=${amount.toStringAsFixed(8)}${description.isNotEmpty ? '&label=$description' : ''}'; - } + final bip21Address = context.select( + (ReceiveCubit x) => x.state.getAddressWithAmountAndLabel( + amount, + isLiquid, + swapTx: swapTx, + ), + ); return AnimatedSwitcher( duration: const Duration(milliseconds: 350), @@ -873,8 +829,7 @@ class _ReceiveDisplayAddressState extends State { Expanded( child: GestureDetector( onTap: () async { - if (locator.isRegistered()) - await locator().copy(finalAddress); + if (locator.isRegistered()) await locator().copy(bip21Address); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( @@ -883,15 +838,14 @@ class _ReceiveDisplayAddressState extends State { ); }, child: BBText.bodySmall( - finalAddress, + bip21Address, isBlue: true, ), ), ), IconButton( onPressed: () async { - if (locator.isRegistered()) - await locator().copy(finalAddress); + if (locator.isRegistered()) await locator().copy(bip21Address); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Copied to clipboard')), @@ -920,8 +874,7 @@ class CreateInvoice extends StatelessWidget { final receiveCubit = context.read(); final currencyCubit = context.read(); - if (currencyCubit.state.amount > 0) - currencyCubit.convertAmtOnCurrencyChange(); + if (currencyCubit.state.amount > 0) currencyCubit.convertAmtOnCurrencyChange(); return showBBBottomSheet( context: context,