diff --git a/lib/models/contact_address_entry_data.dart b/lib/models/contact_address_entry_data.dart index 25677b13d..7c4641302 100644 --- a/lib/models/contact_address_entry_data.dart +++ b/lib/models/contact_address_entry_data.dart @@ -57,7 +57,10 @@ class AddressEntryData extends ChangeNotifier { } bool get isValidAddress { - if (_address == null || coin == null) { + if ( coin == null) { + return true; + } + if (_address == null) { return false; } return AddressUtils.validateAddress(_address!, _coin!); diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart index c08b856c8..ca7236862 100644 --- a/lib/pages/coin_control/utxo_details_view.dart +++ b/lib/pages/coin_control/utxo_details_view.dart @@ -138,270 +138,228 @@ class _UtxoDetailsViewState extends ConsumerState { ), ), child: StreamBuilder( - stream: streamUTXO, - builder: (context, snapshot) { - if (snapshot.hasData) { - utxo = snapshot.data!; - } - return ConditionalParent( - condition: isDesktop, - builder: (child) { - return DesktopDialog( - maxHeight: double.infinity, - child: Column( + stream: streamUTXO, + builder: (context, snapshot) { + if (snapshot.hasData) { + utxo = snapshot.data!; + } + return ConditionalParent( + condition: isDesktop, + builder: (child) { + return DesktopDialog( + maxHeight: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Output details", + style: STextStyles.desktopH3(context), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () { + Navigator.of(context) + .pop(_popWithRefresh ? "refresh" : null); + }, + ), + ], + ), + IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + top: 10, + ), + child: Column( + children: [ + IntrinsicHeight( + child: RoundedContainer( + padding: EdgeInsets.zero, + color: Colors.transparent, + borderColor: Theme.of(context) + .extension()! + .textFieldDefaultBG, + child: child, + ), + ), + const SizedBox( + height: 20, + ), + SecondaryButton( + buttonHeight: ButtonHeight.l, + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + ], + ), + ), + ), + ], + ), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (!isDesktop) + const SizedBox( + height: 10, + ), + RoundedContainer( + padding: const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: const EdgeInsets.only(left: 32), - child: Text( - "Output details", - style: STextStyles.desktopH3(context), + if (isDesktop) + UTXOStatusIcon( + blocked: utxo!.isBlocked, + status: confirmed + ? UTXOStatusIconStatus.confirmed + : UTXOStatusIconStatus.unconfirmed, + background: Theme.of(context) + .extension()! + .popupBG, + selected: false, + width: 32, + height: 32, ), - ), - DesktopDialogCloseButton( - onPressedOverride: () { - Navigator.of(context) - .pop(_popWithRefresh ? "refresh" : null); - }, + if (isDesktop) + const SizedBox( + width: 16, + ), + Text( + "${Format.satoshisToAmount( + utxo!.value, + coin: coin, + ).toStringAsFixed( + coin.decimals, + )} ${coin.ticker}", + style: STextStyles.pageTitleH2(context), ), ], ), - IntrinsicHeight( - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - top: 10, - ), - child: Column( - children: [ - IntrinsicHeight( - child: RoundedContainer( - padding: EdgeInsets.zero, - color: Colors.transparent, - borderColor: Theme.of(context) + Text( + utxo!.isBlocked + ? "Frozen" + : confirmed + ? "Available" + : "Unconfirmed", + style: STextStyles.w500_14(context).copyWith( + color: utxo!.isBlocked + ? const Color(0xFF7FA2D4) // todo theme + : confirmed + ? Theme.of(context) .extension()! - .textFieldDefaultBG, - child: child, - ), - ), - const SizedBox( - height: 20, - ), - SecondaryButton( - buttonHeight: ButtonHeight.l, - label: utxo!.isBlocked ? "Unfreeze" : "Freeze", - onPressed: _toggleFreeze, - ), - ], - ), + .accentColorGreen + : Theme.of(context) + .extension()! + .accentColorYellow, ), ), ], ), - ); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (!isDesktop) - const SizedBox( - height: 10, - ), - RoundedContainer( - padding: const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - if (isDesktop) - UTXOStatusIcon( - blocked: utxo!.isBlocked, - status: confirmed - ? UTXOStatusIconStatus.confirmed - : UTXOStatusIconStatus.unconfirmed, - background: Theme.of(context) - .extension()! - .popupBG, - selected: false, - width: 32, - height: 32, - ), - if (isDesktop) - const SizedBox( - width: 16, - ), - Text( - "${Format.satoshisToAmount( - utxo!.value, - coin: coin, - ).toStringAsFixed( - coin.decimals, - )} ${coin.ticker}", - style: STextStyles.pageTitleH2(context), - ), - ], - ), - Text( - utxo!.isBlocked - ? "Frozen" - : confirmed - ? "Available" - : "Unconfirmed", - style: STextStyles.w500_14(context).copyWith( - color: utxo!.isBlocked - ? const Color(0xFF7FA2D4) // todo theme - : confirmed - ? Theme.of(context) - .extension()! - .accentColorGreen - : Theme.of(context) - .extension()! - .accentColorYellow, - ), - ), - ], - ), - ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Label", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - SimpleEditButton( - editValue: utxo!.name, - editLabel: "label", - onValueChanged: (newName) { - MainDB.instance.putUTXO( - utxo!.copyWith( - name: newName, - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.name, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Address", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: utxo!.address!, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.address!, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - if (label != null && label!.value.isNotEmpty) const _Div(), - if (label != null && label!.value.isNotEmpty) - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Address label", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: label!.value, - ), - ], - ), - const SizedBox( - height: 4, - ), Text( - label!.value, - style: STextStyles.w500_14(context), + "Label", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.name, + editLabel: "label", + onValueChanged: (newName) { + MainDB.instance.putUTXO( + utxo!.copyWith( + name: newName, + ), + ); + }, ), ], ), - ), - const _Div(), + const SizedBox( + height: 4, + ), + Text( + utxo!.name, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Address", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + isDesktop + ? IconCopyButton( + data: utxo!.address!, + ) + : SimpleCopyButton( + data: utxo!.address!, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.address!, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (label != null && label!.value.isNotEmpty) const _Div(), + if (label != null && label!.value.isNotEmpty) RoundedContainer( padding: isDesktop ? const EdgeInsets.all(16) @@ -417,7 +375,7 @@ class _UtxoDetailsViewState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Transaction ID", + "Address label", style: STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension()! @@ -426,10 +384,10 @@ class _UtxoDetailsViewState extends ConsumerState { ), isDesktop ? IconCopyButton( - data: utxo!.address!, + data: label!.value, ) : SimpleCopyButton( - data: utxo!.txid, + data: label!.value, ), ], ), @@ -437,114 +395,155 @@ class _UtxoDetailsViewState extends ConsumerState { height: 4, ), Text( - utxo!.txid, + label!.value, style: STextStyles.w500_14(context), ), ], ), ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Confirmations", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - const SizedBox( - height: 4, - ), - Text( - "${utxo!.getConfirmations(currentHeight)}", - style: STextStyles.w500_14(context), - ), - ], - ), - ), - if (utxo!.isBlocked) const _Div(), - if (utxo!.isBlocked) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context) + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Transaction ID", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) .extension()! - .popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - "Freeze reason", - style: - STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - SimpleEditButton( - editValue: utxo!.blockedReason ?? "", - editLabel: "freeze reason", - onValueChanged: (newReason) { - MainDB.instance.putUTXO( - utxo!.copyWith( - blockedReason: newReason, - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.blockedReason ?? "", - style: STextStyles.w500_14(context), - ), - ], + .textSubtitle1, + ), ), + isDesktop + ? IconCopyButton( + data: utxo!.txid, + ) + : SimpleCopyButton( + data: utxo!.txid, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.txid, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Confirmations", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, ), - if (!isDesktop) const _Div(), - ], - ), - if (!isDesktop) const Spacer(), - if (!isDesktop) - SecondaryButton( - label: utxo!.isBlocked ? "Unfreeze" : "Freeze", - onPressed: _toggleFreeze, - ), - if (!isDesktop) - const SizedBox( - height: 16, - ), - ], - ), - ); - }), + ), + const SizedBox( + height: 4, + ), + Text( + "${utxo!.getConfirmations(currentHeight)}", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (utxo!.isBlocked) const _Div(), + if (utxo!.isBlocked) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context) + .extension()! + .popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Freeze reason", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.blockedReason ?? "", + editLabel: "freeze reason", + onValueChanged: (newReason) { + MainDB.instance.putUTXO( + utxo!.copyWith( + blockedReason: newReason, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.blockedReason ?? "", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (!isDesktop) const _Div(), + ], + ), + if (!isDesktop) const Spacer(), + if (!isDesktop) + SecondaryButton( + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + if (!isDesktop) + const SizedBox( + height: 16, + ), + ], + ), + ); + }, + ), ); } } diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart index 280077819..6521dec0f 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart @@ -282,6 +282,7 @@ abstract class SWB { backupWallet['id'] = manager.walletId; backupWallet['isFavorite'] = manager.isFavorite; backupWallet['mnemonic'] = await manager.mnemonic; + backupWallet['mnemonicPassphrase'] = await manager.mnemonicPassphrase; backupWallet['coinName'] = manager.coin.name; backupWallet['storedChainHeight'] = DB.instance .get(boxName: manager.walletId, key: 'storedChainHeight'); @@ -363,6 +364,7 @@ abstract class SWB { walletId: manager.walletId, restoringStatus: StackRestoringStatus.restoring, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); if (_shouldCancelRestore) { @@ -432,6 +434,7 @@ abstract class SWB { address: currentAddress, height: restoreHeight, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); } catch (e, s) { Logging.instance.log("$e $s", level: LogLevel.Warning); @@ -440,6 +443,7 @@ abstract class SWB { restoringStatus: StackRestoringStatus.failed, manager: manager, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); return false; } diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index cb5b124a1..17af5d914 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2490,60 +2490,17 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { }); } - // final int utxosIntValue = utxos.satoshiBalance; - // final Decimal utxosValue = - // Format.satoshisToAmount(utxosIntValue, coin: coin); - - // List balances = List.empty(growable: true); - // - // Decimal lelantusBalance = - // Format.satoshisToAmount(intLelantusBalance, coin: coin); - - // balances.add(lelantusBalance); 0 - // - // balances.add(lelantusBalance * price); 1 - - // Decimal _unconfirmedLelantusBalance = - // Format.satoshisToAmount(unconfirmedLelantusBalance, coin: coin); - - // balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance); 2 - // - // balances.add( - // (lelantusBalance + utxosValue + _unconfirmedLelantusBalance) * price); 3 - - // int availableSats = - // utxos.satoshiBalance - utxos.satoshiBalanceUnconfirmed; - // if (availableSats < 0) { - // availableSats = 0; - // } - // balances.add(Format.satoshisToAmount(availableSats, coin: coin)); 4 + _balancePrivate = Balance( + coin: coin, + total: intLelantusBalance + unconfirmedLelantusBalance, + spendable: intLelantusBalance, + blockedTotal: 0, + pendingSpendable: unconfirmedLelantusBalance, + ); + await updateCachedBalanceSecondary(_balancePrivate!); // wait for updated uxtos to get updated public balance await utxosUpdateFuture; - - // todo: shared total between private and public balances? - _balancePrivate = Balance( - coin: coin, - total: intLelantusBalance + unconfirmedLelantusBalance + balance.total, - spendable: intLelantusBalance, - blockedTotal: 0, - pendingSpendable: unconfirmedLelantusBalance + balance.total, - ); - await updateCachedBalanceSecondary(_balancePrivate!); - // _balance = Balance( - // coin: coin, - // total: utxos.satoshiBalance, - // spendable: availableSats, - // blockedTotal: 0, - // pendingSpendable: utxos.satoshiBalanceUnconfirmed, - // ); - - // Logging.instance.log("balances $balances", level: LogLevel.Info); - // await DB.instance.put( - // boxName: walletId, - // key: 'totalBalance', - // value: balances[2].toString()); - // return balances; } catch (e, s) { Logging.instance.log("Exception rethrown in getFullBalance(): $e\n$s", level: LogLevel.Error); diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart index 194033de3..5812a86e4 100644 --- a/lib/widgets/wallet_card.dart +++ b/lib/widgets/wallet_card.dart @@ -33,22 +33,24 @@ class WalletSheetCard extends ConsumerWidget { ), ), onPressed: () async { - final manager = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId); - if (manager.coin == Coin.monero || - manager.coin == Coin.wownero) { + final manager = + ref.read(walletsChangeNotifierProvider).getManager(walletId); + if (manager.coin == Coin.monero || manager.coin == Coin.wownero) { await manager.initializeExisting(); } - if (popPrevious) Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - WalletView.routeName, - arguments: Tuple2( + if (context.mounted) { + if (popPrevious && context.mounted) Navigator.of(context).pop(); + + await Navigator.of(context).pushNamed( + WalletView.routeName, + arguments: Tuple2( walletId, ref .read(walletsChangeNotifierProvider) - .getManagerProvider(walletId)), - ); + .getManagerProvider(walletId), + ), + ); + } }, child: WalletInfoRow( walletId: walletId,