From c76bcd81e727a8d3a66f199e2b5bdb79da36eec4 Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 10 Apr 2023 16:03:04 -0600 Subject: [PATCH 01/14] never rescan on open for eth --- .../my_stack_view/wallet_view/desktop_wallet_view.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 7e786ace6..adb3da885 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -21,6 +21,7 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/background.dart'; @@ -104,7 +105,8 @@ class _DesktopWalletViewState extends ConsumerState { _shouldDisableAutoSyncOnLogOut = false; } - if (ref.read(managerProvider).rescanOnOpenVersion == Constants.rescanV1) { + if (ref.read(managerProvider).coin != Coin.ethereum && + ref.read(managerProvider).rescanOnOpenVersion == Constants.rescanV1) { _rescanningOnOpen = true; ref.read(managerProvider).fullRescan(20, 1000).then( (_) => ref.read(managerProvider).resetRescanOnOpen().then( From 7e95b3a00fa84b3c1b824acb00e75ba775d3455e Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 10 Apr 2023 16:10:59 -0600 Subject: [PATCH 02/14] desktop wallets not showing properly fix --- .../my_stack_view/wallet_summary_table.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart index 505906849..70189b383 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart @@ -37,10 +37,11 @@ class _WalletTableState extends ConsumerState { return ConditionalParent( condition: index + 1 == providersByCoin.length, - builder: (child) => const Padding( - padding: EdgeInsets.only( + builder: (child) => Padding( + padding: const EdgeInsets.only( bottom: 16, ), + child: child, ), child: DesktopWalletSummaryRow( key: Key("DesktopWalletSummaryRow_key_${coin.name}"), From 059fd22c2165e5da7de6b5bbdfdee7dedaec84ab Mon Sep 17 00:00:00 2001 From: julian Date: Mon, 10 Apr 2023 16:12:14 -0600 Subject: [PATCH 03/14] desktop wallets overview background fix --- lib/pages/wallets_view/wallets_overview.dart | 230 +++++++++---------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/lib/pages/wallets_view/wallets_overview.dart b/lib/pages/wallets_view/wallets_overview.dart index bc68ec30b..8d7f9b6ac 100644 --- a/lib/pages/wallets_view/wallets_overview.dart +++ b/lib/pages/wallets_view/wallets_overview.dart @@ -162,10 +162,10 @@ class _EthWalletsOverviewState extends ConsumerState { @override Widget build(BuildContext context) { - return Background( - child: ConditionalParent( - condition: !isDesktop, - builder: (child) => Scaffold( + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, appBar: AppBar( @@ -182,126 +182,126 @@ class _EthWalletsOverviewState extends ConsumerState { ), ), ), - child: Column( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - autocorrect: !isDesktop, - enableSuggestions: !isDesktop, - controller: _searchController, - focusNode: searchFieldFocusNode, - onChanged: (value) { - setState(() { - _searchString = value; - }); - }, - style: isDesktop - ? STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textFieldActiveText, - height: 1.8, - ) - : STextStyles.field(context), - decoration: standardInputDecoration( - "Search...", - searchFieldFocusNode, - context, - desktopMed: isDesktop, - ).copyWith( - prefixIcon: Padding( - padding: EdgeInsets.symmetric( - horizontal: isDesktop ? 12 : 10, - vertical: isDesktop ? 18 : 16, - ), - child: SvgPicture.asset( - Assets.svg.search, - width: isDesktop ? 20 : 16, - height: isDesktop ? 20 : 16, - ), + ), + child: Column( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: _searchController, + focusNode: searchFieldFocusNode, + onChanged: (value) { + setState(() { + _searchString = value; + }); + }, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + decoration: standardInputDecoration( + "Search...", + searchFieldFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + prefixIcon: Padding( + padding: EdgeInsets.symmetric( + horizontal: isDesktop ? 12 : 10, + vertical: isDesktop ? 18 : 16, + ), + child: SvgPicture.asset( + Assets.svg.search, + width: isDesktop ? 20 : 16, + height: isDesktop ? 20 : 16, ), - suffixIcon: _searchController.text.isNotEmpty - ? Padding( - padding: const EdgeInsets.only(right: 0), - child: UnconstrainedBox( - child: Row( - children: [ - TextFieldIconButton( - child: const XIcon(), - onTap: () async { - setState(() { - _searchController.text = ""; - _searchString = ""; - }); - }, - ), - ], - ), - ), - ) - : null, ), + suffixIcon: _searchController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _searchController.text = ""; + _searchString = ""; + }); + }, + ), + ], + ), + ), + ) + : null, ), ), - const SizedBox( - height: 16, - ), - Expanded( - child: Builder( - builder: (context) { - final data = _filter(_searchString); - return ListView.separated( - itemBuilder: (_, index) { - final element = data[index]; + ), + const SizedBox( + height: 16, + ), + Expanded( + child: Builder( + builder: (context) { + final data = _filter(_searchString); + return ListView.separated( + itemBuilder: (_, index) { + final element = data[index]; - if (element.item1.hasTokenSupport) { - if (isDesktop) { - return DesktopExpandingWalletCard( - key: Key( - "${element.item1.walletName}_${element.item2.map((e) => e.address).join()}"), - data: element, - navigatorState: widget.navigatorState!, - ); - } else { - return MasterWalletCard( - walletId: element.item1.walletId, - ); - } + if (element.item1.hasTokenSupport) { + if (isDesktop) { + return DesktopExpandingWalletCard( + key: Key( + "${element.item1.walletName}_${element.item2.map((e) => e.address).join()}"), + data: element, + navigatorState: widget.navigatorState!, + ); } else { - return ConditionalParent( - condition: isDesktop, - builder: (child) => RoundedWhiteContainer( - padding: const EdgeInsets.symmetric( - vertical: 14, - horizontal: 20, - ), - borderColor: Theme.of(context) - .extension()! - .backgroundAppBar, - child: child, - ), - child: SimpleWalletCard( - walletId: element.item1.walletId, - popPrevious: isDesktop, - desktopNavigatorState: - isDesktop ? widget.navigatorState : null, - ), + return MasterWalletCard( + walletId: element.item1.walletId, ); } - }, - separatorBuilder: (_, __) => SizedBox( - height: isDesktop ? 10 : 8, - ), - itemCount: data.length, - ); - }, - ), + } else { + return ConditionalParent( + condition: isDesktop, + builder: (child) => RoundedWhiteContainer( + padding: const EdgeInsets.symmetric( + vertical: 14, + horizontal: 20, + ), + borderColor: Theme.of(context) + .extension()! + .backgroundAppBar, + child: child, + ), + child: SimpleWalletCard( + walletId: element.item1.walletId, + popPrevious: isDesktop, + desktopNavigatorState: + isDesktop ? widget.navigatorState : null, + ), + ); + } + }, + separatorBuilder: (_, __) => SizedBox( + height: isDesktop ? 10 : 8, + ), + itemCount: data.length, + ); + }, ), - ], - ), + ), + ], ), ); } From b6675146620666b49c343d897775c7122505af7b Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 08:02:27 -0600 Subject: [PATCH 04/14] expand coin selection on add wallet screen quicker --- lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart index 2307d0591..3f78bda33 100644 --- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart +++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart @@ -265,11 +265,13 @@ class _AddWalletViewState extends ConsumerState { title: "Coins", entities: filter(_searchTerm, coinEntities), initialState: ExpandableState.expanded, + animationDurationMultiplier: 0.5, ), ExpandingSubListItem( title: "Tokens", entities: filter(_searchTerm, tokenEntities), initialState: ExpandableState.expanded, + animationDurationMultiplier: 0.5, trailing: AddCustomTokenSelector( addFunction: _addToken, ), From aeaad3918237bf8e180419cc7823837a76137e10 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 08:28:05 -0600 Subject: [PATCH 05/14] style fix --- lib/widgets/custom_tab_view.dart | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/widgets/custom_tab_view.dart b/lib/widgets/custom_tab_view.dart index 49fd81d18..6d89499a3 100644 --- a/lib/widgets/custom_tab_view.dart +++ b/lib/widgets/custom_tab_view.dart @@ -22,7 +22,6 @@ class CustomTabView extends StatefulWidget { } class _CustomTabViewState extends State { - final _key = GlobalKey(); late int _selectedIndex; static const duration = Duration(milliseconds: 250); @@ -80,6 +79,9 @@ class _CustomTabViewState extends State { : CrossFadeState.showSecond, duration: const Duration(milliseconds: 250), ), + const SizedBox( + height: 19, + ), ], ), ), @@ -88,9 +90,6 @@ class _CustomTabViewState extends State { ), ], ), - const SizedBox( - height: 19, - ), Stack( children: [ Container( @@ -117,7 +116,6 @@ class _CustomTabViewState extends State { ], ), AnimatedSwitcher( - key: _key, duration: duration, transitionBuilder: (child, animation) { return FadeTransition( @@ -135,7 +133,7 @@ class _CustomTabViewState extends State { ); }, child: AnimatedAlign( - key: Key(widget.titles[_selectedIndex]), + key: Key("${widget.titles[_selectedIndex]}_customTabKey"), alignment: Alignment.topCenter, duration: duration, child: Padding( From b3efbda2e4f82c8349fd601f94d322ce09171c10 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 09:17:58 -0600 Subject: [PATCH 06/14] some amount sending fixes --- .../send_view/confirm_transaction_view.dart | 11 ++---- .../coins/bitcoin/bitcoin_wallet.dart | 25 ++++++++++--- .../coins/bitcoincash/bitcoincash_wallet.dart | 25 ++++++++++--- .../coins/dogecoin/dogecoin_wallet.dart | 25 ++++++++++--- .../coins/epiccash/epiccash_wallet.dart | 15 +++++--- lib/services/coins/firo/firo_wallet.dart | 37 +++++++++++-------- .../coins/litecoin/litecoin_wallet.dart | 25 ++++++++++--- .../coins/namecoin/namecoin_wallet.dart | 25 ++++++++++--- .../coins/particl/particl_wallet.dart | 25 ++++++++++--- 9 files changed, 154 insertions(+), 59 deletions(-) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 9f9b7c9df..bb5c5b71c 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -544,10 +544,8 @@ class _ConfirmTransactionViewState (value) => value.coin, ), ); - final amount = Amount( - rawValue: BigInt.from( - transactionInfo["recipientAmt"] as int), - fractionDigits: coin.decimals); + final amount = + transactionInfo["recipientAmt"] as Amount; final externalCalls = ref.watch( prefsChangeNotifierProvider.select( (value) => value.externalCalls)); @@ -924,10 +922,7 @@ class _ConfirmTransactionViewState localeServiceChangeNotifierProvider .select((value) => value.locale), ); - final amount = Amount( - rawValue: BigInt.from( - transactionInfo["recipientAmt"] as int), - fractionDigits: coin.decimals); + final amount = transactionInfo["recipientAmt"] as Amount; return Text( "${(amount + fee).localizedStringAsFixed( locale: locale, diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index 4184fd282..21947fdaf 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -2437,7 +2437,10 @@ class BitcoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2566,7 +2569,10 @@ class BitcoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2593,7 +2599,10 @@ class BitcoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2622,7 +2631,10 @@ class BitcoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2651,7 +2663,10 @@ class BitcoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index bbdd540f0..a2a54cba1 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2510,7 +2510,10 @@ class BitcoinCashWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoObjectsToUse, @@ -2643,7 +2646,10 @@ class BitcoinCashWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoObjectsToUse, @@ -2671,7 +2677,10 @@ class BitcoinCashWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoObjectsToUse, @@ -2701,7 +2710,10 @@ class BitcoinCashWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoObjectsToUse, @@ -2731,7 +2743,10 @@ class BitcoinCashWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoObjectsToUse, diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 1caafd791..8db10cc37 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -2192,7 +2192,10 @@ class DogecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2321,7 +2324,10 @@ class DogecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2348,7 +2354,10 @@ class DogecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2377,7 +2386,10 @@ class DogecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2406,7 +2418,10 @@ class DogecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index c15a5bee3..7a39ebb9b 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -478,8 +478,8 @@ class EpicCashWallet extends CoinServiceAPI "selectionStrategyIsAll": selectionStrategyIsAll, "minimumConfirmations": MINIMUM_CONFIRMATIONS, "message": "", - "amount": txData['recipientAmt'], - "address": txData['addresss'] + "amount": (txData['recipientAmt'] as Amount).raw.toInt(), + "address": (txData['addresss'] as Amount).raw.toInt(), }, name: walletName); message = await receivePort.first; @@ -496,8 +496,8 @@ class EpicCashWallet extends CoinServiceAPI ReceivePort receivePort = await getIsolate({ "function": "createTransaction", "wallet": wallet!, - "amount": txData['recipientAmt'], - "address": txData['addresss'], + "amount": (txData['recipientAmt'] as Amount).raw.toInt(), + "address": (txData['addresss'] as Amount).raw.toInt(), "secretKeyIndex": 0, "epicboxConfig": epicboxConfig.toString(), "minimumConfirmations": MINIMUM_CONFIRMATIONS, @@ -872,7 +872,10 @@ class EpicCashWallet extends CoinServiceAPI Map txData = { "fee": realfee, "addresss": address, - "recipientAmt": satAmount, + "recipientAmt": Amount( + rawValue: BigInt.from(satAmount), + fractionDigits: coin.decimals, + ), }; Logging.instance.log("prepare send: $txData", level: LogLevel.Info); @@ -913,7 +916,7 @@ class EpicCashWallet extends CoinServiceAPI debugPrint(transactionFees); dynamic decodeData; - final available = balance.spendable; + final available = balance.spendable.raw.toInt(); if (available == satoshiAmount) { if (transactionFees!.contains("Required")) { diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 665ab063a..24c5b0343 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -914,16 +914,8 @@ class FiroWallet extends CoinServiceAPI type: isar_models.TransactionType.outgoing, subType: isar_models.TransactionSubType.none, // precision may be lost here hence the following amountString - amount: Amount( - rawValue: BigInt.from(txData["recipientAmt"] as int), - fractionDigits: coin.decimals) - .raw - .toInt(), - amountString: Amount( - rawValue: BigInt.from(txData["recipientAmt"] as int), - fractionDigits: coin.decimals) - .raw - .toString(), + amount: (txData["recipientAmt"] as Amount).raw.toInt(), + amountString: (txData["recipientAmt"] as Amount).toJsonString(), fee: txData["fee"] as int, height: null, isCancelled: false, @@ -1422,7 +1414,10 @@ class FiroWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], }; @@ -1549,7 +1544,10 @@ class FiroWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], }; @@ -1575,7 +1573,10 @@ class FiroWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], }; @@ -1603,7 +1604,10 @@ class FiroWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], }; @@ -1631,7 +1635,10 @@ class FiroWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], }; diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index b3876d3c3..f3598efe6 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -2387,7 +2387,10 @@ class LitecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2502,7 +2505,10 @@ class LitecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2529,7 +2535,10 @@ class LitecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2558,7 +2567,10 @@ class LitecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2587,7 +2599,10 @@ class LitecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index 5538ffde5..b0706abb4 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -2377,7 +2377,10 @@ class NamecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2492,7 +2495,10 @@ class NamecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2519,7 +2525,10 @@ class NamecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2548,7 +2557,10 @@ class NamecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2577,7 +2589,10 @@ class NamecoinWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), diff --git a/lib/services/coins/particl/particl_wallet.dart b/lib/services/coins/particl/particl_wallet.dart index 1c0a231e1..15c7b0b65 100644 --- a/lib/services/coins/particl/particl_wallet.dart +++ b/lib/services/coins/particl/particl_wallet.dart @@ -2543,7 +2543,10 @@ class ParticlWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": amount, + "recipientAmt": Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2658,7 +2661,10 @@ class ParticlWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeBeingPaid, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2685,7 +2691,10 @@ class ParticlWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2714,7 +2723,10 @@ class ParticlWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": satoshisBeingUsed - satoshiAmountToSend, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), @@ -2743,7 +2755,10 @@ class ParticlWallet extends CoinServiceAPI Map transactionObject = { "hex": txn["hex"], "recipient": recipientsArray[0], - "recipientAmt": recipientsAmtArray[0], + "recipientAmt": Amount( + rawValue: BigInt.from(recipientsAmtArray[0]), + fractionDigits: coin.decimals, + ), "fee": feeForOneOutput, "vSize": txn["vSize"], "usedUTXOs": utxoSigningData.map((e) => e.utxo).toList(), From b2d2f20b50404769dc5443f0ef34cb14e416f075 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 09:18:29 -0600 Subject: [PATCH 07/14] WIP replacement for `Map transactionObject` --- lib/models/tx_info.dart | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 lib/models/tx_info.dart diff --git a/lib/models/tx_info.dart b/lib/models/tx_info.dart new file mode 100644 index 000000000..798cb5adc --- /dev/null +++ b/lib/models/tx_info.dart @@ -0,0 +1,45 @@ +import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; + +// TODO use something like this instead of Map transactionObject + +class TxInfo { + final String hex; + final List recipients; + final Amount fee; + final int vSize; + final List? usedUTXOs; + + TxInfo({ + required this.hex, + required this.recipients, + required this.fee, + required this.vSize, + required this.usedUTXOs, + }); + + TxInfo copyWith({ + String? hex, + List? recipients, + Amount? fee, + int? vSize, + List? usedUTXOs, + }) => + TxInfo( + hex: hex ?? this.hex, + fee: fee ?? this.fee, + vSize: vSize ?? this.vSize, + usedUTXOs: usedUTXOs ?? this.usedUTXOs, + recipients: recipients ?? this.recipients, + ); +} + +class TxRecipient { + final String address; + final Amount amount; + + TxRecipient({ + required this.address, + required this.amount, + }); +} From ce67673a9438b2fb27feaa0f0aa4626dbcb853f7 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 09:53:26 -0600 Subject: [PATCH 08/14] duplicated lower cased eth address fix --- lib/services/coins/ethereum/ethereum_wallet.dart | 10 ++++++---- lib/services/ethereum/ethereum_token_service.dart | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/ethereum/ethereum_wallet.dart b/lib/services/coins/ethereum/ethereum_wallet.dart index 380f4dc04..797388f67 100644 --- a/lib/services/coins/ethereum/ethereum_wallet.dart +++ b/lib/services/coins/ethereum/ethereum_wallet.dart @@ -201,7 +201,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { Future get currentReceivingAddress async { final address = await _currentReceivingAddress; return checksumEthereumAddress( - address?.value ?? _credentials.address.toString()); + address?.value ?? _credentials.address.hexEip55); } Future get _currentReceivingAddress => db @@ -362,7 +362,8 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { _credentials = web3.EthPrivateKey.fromHex(privateKey); final address = Address( - walletId: walletId, value: _credentials.address.toString(), + walletId: walletId, + value: _credentials.address.hexEip55, publicKey: [], // maybe store address bytes here? seems a waste of space though derivationIndex: 0, derivationPath: DerivationPath()..value = "$hdPathEthereum/0", @@ -566,7 +567,8 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { _credentials = web3.EthPrivateKey.fromHex(privateKey); final address = Address( - walletId: walletId, value: _credentials.address.toString(), + walletId: walletId, + value: _credentials.address.hexEip55, publicKey: [], // maybe store address bytes here? seems a waste of space though derivationIndex: 0, derivationPath: DerivationPath()..value = "$hdPathEthereum/0", @@ -909,7 +911,7 @@ class EthereumWallet extends CoinServiceAPI with WalletCache, WalletDB { @override Future updateSentCachedTxData(Map txData) async { final txid = txData["txid"] as String; - final addressString = txData["address"] as String; + final addressString = checksumEthereumAddress(txData["address"] as String); final response = await EthereumAPI.getEthTransactionByHash(txid); final transaction = Transaction( diff --git a/lib/services/ethereum/ethereum_token_service.dart b/lib/services/ethereum/ethereum_token_service.dart index 1f930cf4c..48eff2f00 100644 --- a/lib/services/ethereum/ethereum_token_service.dart +++ b/lib/services/ethereum/ethereum_token_service.dart @@ -167,7 +167,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache { Future updateSentCachedTxData(Map txData) async { final txid = txData["txid"] as String; - final addressString = txData["address"] as String; + final addressString = checksumEthereumAddress(txData["address"] as String); final response = await EthereumAPI.getEthTransactionByHash(txid); final transaction = Transaction( From 32987b46a932a692feeca44c245d553362fa0006 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 09:59:24 -0600 Subject: [PATCH 09/14] desktop address list state bugfix --- .../addresses/desktop_wallet_addresses_view.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart b/lib/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart index 54c5f4daa..3ba175b73 100644 --- a/lib/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart +++ b/lib/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart @@ -35,11 +35,13 @@ class _DesktopWalletAddressesViewState static const _headerHeight = 70.0; static const _columnWidth0 = 489.0; - late final Stream addressCollectionWatcher; + Stream? addressCollectionWatcher; void _onAddressCollectionWatcherEvent() { WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() {}); + if (mounted) { + setState(() {}); + } }); } @@ -50,13 +52,14 @@ class _DesktopWalletAddressesViewState .isar .addresses .watchLazy(fireImmediately: true); - addressCollectionWatcher.listen((_) => _onAddressCollectionWatcherEvent()); + addressCollectionWatcher!.listen((_) => _onAddressCollectionWatcherEvent()); super.initState(); } @override void dispose() { + addressCollectionWatcher = null; super.dispose(); } From 2004abdfccfb4a1fe46cf8468dec80cf31a8fabd Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 10:05:15 -0600 Subject: [PATCH 10/14] desktop my tokens list text color fix --- .../token_view/sub_widgets/my_token_select_item.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/pages/token_view/sub_widgets/my_token_select_item.dart b/lib/pages/token_view/sub_widgets/my_token_select_item.dart index f6a327f52..50b6e9768 100644 --- a/lib/pages/token_view/sub_widgets/my_token_select_item.dart +++ b/lib/pages/token_view/sub_widgets/my_token_select_item.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/icon_widgets/eth_token_icon.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -117,6 +118,11 @@ class _MyTokenSelectItemState extends ConsumerState { widget.token.name, style: isDesktop ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) : STextStyles.titleBold12(context), ), const Spacer(), @@ -131,6 +137,11 @@ class _MyTokenSelectItemState extends ConsumerState { "${widget.token.symbol}", style: isDesktop ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ) : STextStyles.itemSubtitle(context), ), ], From 2e72a846a9f6c62ff81142f40596ba79c49033df Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 10:12:26 -0600 Subject: [PATCH 11/14] set controller to null on dispose to prevent any attempts at use after the widget was disposed --- lib/widgets/custom_buttons/blue_text_button.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/widgets/custom_buttons/blue_text_button.dart b/lib/widgets/custom_buttons/blue_text_button.dart index 213dc55cc..5450620b6 100644 --- a/lib/widgets/custom_buttons/blue_text_button.dart +++ b/lib/widgets/custom_buttons/blue_text_button.dart @@ -64,6 +64,7 @@ class _CustomTextButtonState extends State<_CustomTextButton> @override void dispose() { controller?.dispose(); + controller = null; super.dispose(); } From 347c69339c15d69007041976c31d1caeb91600df Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 11:09:24 -0600 Subject: [PATCH 12/14] fix tests --- .../coins/bitcoin/bitcoin_wallet_test.dart | 9 ++- .../bitcoincash/bitcoincash_wallet_test.dart | 40 +++-------- .../coins/dogecoin/dogecoin_wallet_test.dart | 40 +++-------- test/services/coins/manager_test.dart | 21 +++--- .../coins/namecoin/namecoin_wallet_test.dart | 9 ++- .../coins/particl/particl_wallet_test.dart | 9 ++- test/widget_tests/managed_favorite_test.dart | 3 - .../table_view/table_view_row_test.dart | 1 - test/widget_tests/wallet_card_test.dart | 72 ------------------- .../wallet_info_row_balance_future_test.dart | 1 - .../wallet_info_row/wallet_info_row_test.dart | 1 - 11 files changed, 49 insertions(+), 157 deletions(-) diff --git a/test/services/coins/bitcoin/bitcoin_wallet_test.dart b/test/services/coins/bitcoin/bitcoin_wallet_test.dart index aa9f3bb9d..1df1937ce 100644 --- a/test/services/coins/bitcoin/bitcoin_wallet_test.dart +++ b/test/services/coins/bitcoin/bitcoin_wallet_test.dart @@ -9,6 +9,7 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -27,7 +28,13 @@ void main() async { expect(MINIMUM_CONFIRMATIONS, 1); }); test("bitcoin dust limit", () async { - expect(DUST_LIMIT, 294); + expect( + DUST_LIMIT, + Amount( + rawValue: BigInt.from(294), + fractionDigits: 8, + ), + ); }); test("bitcoin mainnet genesis block hash", () async { expect(GENESIS_HASH_MAINNET, diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index 604bb741e..9fad50494 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -28,7 +29,13 @@ void main() async { expect(MINIMUM_CONFIRMATIONS, 0); }); test("bitcoincash dust limit", () async { - expect(DUST_LIMIT, 546); + expect( + DUST_LIMIT, + Amount( + rawValue: BigInt.from(546), + fractionDigits: 8, + ), + ); }); test("bitcoincash mainnet genesis block hash", () async { expect(GENESIS_HASH_MAINNET, @@ -520,37 +527,6 @@ void main() async { verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); }); - - test("get maxFee", () async { - when(client?.ping()).thenAnswer((_) async => true); - when(client?.getServerFeatures()).thenAnswer((_) async => { - "hosts": {}, - "pruning": null, - "server_version": "Unit tests", - "protocol_min": "1.4", - "protocol_max": "1.4.2", - "genesis_hash": GENESIS_HASH_TESTNET, - "hash_function": "sha256", - "services": [] - }); - when(client?.estimateFee(blocks: 20)) - .thenAnswer((realInvocation) async => Decimal.zero); - when(client?.estimateFee(blocks: 5)) - .thenAnswer((realInvocation) async => Decimal.one); - when(client?.estimateFee(blocks: 1)) - .thenAnswer((realInvocation) async => Decimal.ten); - - final maxFee = await bch?.maxFee; - expect(maxFee, 1000000000); - - verify(client?.estimateFee(blocks: 1)).called(1); - verify(client?.estimateFee(blocks: 5)).called(1); - verify(client?.estimateFee(blocks: 20)).called(1); - expect(secureStore.interactions, 0); - verifyNoMoreInteractions(client); - verifyNoMoreInteractions(cachedClient); - verifyNoMoreInteractions(tracker); - }); }); group("BCHWallet service class functions that depend on shared storage", () { diff --git a/test/services/coins/dogecoin/dogecoin_wallet_test.dart b/test/services/coins/dogecoin/dogecoin_wallet_test.dart index 9e117d2ca..712000aae 100644 --- a/test/services/coins/dogecoin/dogecoin_wallet_test.dart +++ b/test/services/coins/dogecoin/dogecoin_wallet_test.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/dogecoin/dogecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -28,7 +29,13 @@ void main() { expect(MINIMUM_CONFIRMATIONS, 1); }); test("dogecoin dust limit", () async { - expect(DUST_LIMIT, 1000000); + expect( + DUST_LIMIT, + Amount( + rawValue: BigInt.from(1000000), + fractionDigits: 8, + ), + ); }); test("dogecoin mainnet genesis block hash", () async { expect(GENESIS_HASH_MAINNET, @@ -366,37 +373,6 @@ void main() { verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); }); - - test("get maxFee", () async { - when(client?.ping()).thenAnswer((_) async => true); - when(client?.getServerFeatures()).thenAnswer((_) async => { - "hosts": {}, - "pruning": null, - "server_version": "Unit tests", - "protocol_min": "1.4", - "protocol_max": "1.4.2", - "genesis_hash": GENESIS_HASH_TESTNET, - "hash_function": "sha256", - "services": [] - }); - when(client?.estimateFee(blocks: 20)) - .thenAnswer((realInvocation) async => Decimal.zero); - when(client?.estimateFee(blocks: 5)) - .thenAnswer((realInvocation) async => Decimal.one); - when(client?.estimateFee(blocks: 1)) - .thenAnswer((realInvocation) async => Decimal.ten); - - final maxFee = await doge?.maxFee; - expect(maxFee, 1000000000); - - verify(client?.estimateFee(blocks: 1)).called(1); - verify(client?.estimateFee(blocks: 5)).called(1); - verify(client?.estimateFee(blocks: 20)).called(1); - expect(secureStore.interactions, 0); - verifyNoMoreInteractions(client); - verifyNoMoreInteractions(cachedClient); - verifyNoMoreInteractions(tracker); - }); }); group("DogeWallet service class functions that depend on shared storage", () { diff --git a/test/services/coins/manager_test.dart b/test/services/coins/manager_test.dart index 6704294b0..65a2de918 100644 --- a/test/services/coins/manager_test.dart +++ b/test/services/coins/manager_test.dart @@ -83,24 +83,21 @@ void main() { group("get balances", () { test("balance", () async { final CoinServiceAPI wallet = MockFiroWallet(); + final balance = Balance( + total: _a(10), + spendable: _a(1), + blockedTotal: _a(0), + pendingSpendable: _a(9), + ); + when(wallet.coin).thenAnswer((_) => Coin.firo); when(wallet.balance).thenAnswer( - (_) => Balance( - coin: Coin.firo, - total: _a(10), - spendable: _a(1), - blockedTotal: _a(0), - pendingSpendable: _a(9), - ), + (_) => balance, ); final manager = Manager(wallet); - expect(manager.balance.coin, Coin.firo); - expect(manager.balance.total.raw.toInt(), 10); - expect(manager.balance.spendable.raw.toInt(), 1); - expect(manager.balance.blockedTotal.raw.toInt(), 0); - expect(manager.balance.pendingSpendable.raw.toInt(), 9); + expect(manager.balance, balance); }); }); diff --git a/test/services/coins/namecoin/namecoin_wallet_test.dart b/test/services/coins/namecoin/namecoin_wallet_test.dart index c62abf7da..3fa93b505 100644 --- a/test/services/coins/namecoin/namecoin_wallet_test.dart +++ b/test/services/coins/namecoin/namecoin_wallet_test.dart @@ -9,6 +9,7 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/namecoin/namecoin_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -27,7 +28,13 @@ void main() { expect(MINIMUM_CONFIRMATIONS, 2); }); test("namecoin dust limit", () async { - expect(DUST_LIMIT, 546); + expect( + DUST_LIMIT, + Amount( + rawValue: BigInt.from(546), + fractionDigits: 8, + ), + ); }); test("namecoin mainnet genesis block hash", () async { expect(GENESIS_HASH_MAINNET, diff --git a/test/services/coins/particl/particl_wallet_test.dart b/test/services/coins/particl/particl_wallet_test.dart index 4f4d0be2c..41eadff70 100644 --- a/test/services/coins/particl/particl_wallet_test.dart +++ b/test/services/coins/particl/particl_wallet_test.dart @@ -9,6 +9,7 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/services/coins/particl/particl_wallet.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; @@ -28,7 +29,13 @@ void main() { 1); // TODO confirm particl minimum confirmations }); test("particl dust limit", () async { - expect(DUST_LIMIT, 294); // TODO confirm particl dust limit + expect( + DUST_LIMIT, + Amount( + rawValue: BigInt.from(294), + fractionDigits: 8, + ), + ); // TODO confirm particl dust limit }); test("particl mainnet genesis block hash", () async { expect(GENESIS_HASH_MAINNET, diff --git a/test/widget_tests/managed_favorite_test.dart b/test/widget_tests/managed_favorite_test.dart index 351c83cee..f51e272c0 100644 --- a/test/widget_tests/managed_favorite_test.dart +++ b/test/widget_tests/managed_favorite_test.dart @@ -53,7 +53,6 @@ void main() { .thenAnswer((realInvocation) => manager); when(manager.balance).thenAnswer( (realInvocation) => Balance( - coin: Coin.bitcoin, total: _a(10), spendable: _a(10), blockedTotal: _a(0), @@ -106,7 +105,6 @@ void main() { .thenAnswer((realInvocation) => manager); when(manager.balance).thenAnswer( (realInvocation) => Balance( - coin: Coin.bitcoin, total: _a(10), spendable: _a(10), blockedTotal: _a(0), @@ -177,7 +175,6 @@ void main() { when(manager.isFavorite).thenAnswer((realInvocation) => true); when(manager.balance).thenAnswer( (realInvocation) => Balance( - coin: Coin.bitcoin, total: _a(10), spendable: _a(10), blockedTotal: _a(0), diff --git a/test/widget_tests/table_view/table_view_row_test.dart b/test/widget_tests/table_view/table_view_row_test.dart index c8d17609b..2b0083ca7 100644 --- a/test/widget_tests/table_view/table_view_row_test.dart +++ b/test/widget_tests/table_view/table_view_row_test.dart @@ -40,7 +40,6 @@ void main() { when(wallet.walletId).thenAnswer((_) => "Wallet id 1"); when(wallet.balance).thenAnswer( (_) => Balance( - coin: Coin.bitcoin, total: Amount.zero, spendable: Amount.zero, blockedTotal: Amount.zero, diff --git a/test/widget_tests/wallet_card_test.dart b/test/widget_tests/wallet_card_test.dart index fe2479e1e..8a5647ae2 100644 --- a/test/widget_tests/wallet_card_test.dart +++ b/test/widget_tests/wallet_card_test.dart @@ -2,7 +2,6 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockingjay/mockingjay.dart' as mockingjay; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart' as mockito; import 'package:stackwallet/models/balance.dart'; @@ -17,7 +16,6 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/theme/light_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/wallet_card.dart'; -import 'package:tuple/tuple.dart'; import 'wallet_card_test.mocks.dart'; @@ -30,75 +28,6 @@ Amount _a(int i) => Amount.fromDecimal( @GenerateMocks([Wallets, BitcoinWallet, LocaleService]) void main() { - testWidgets("Test button pressed", (widgetTester) async { - final CoinServiceAPI wallet = MockBitcoinWallet(); - mockito.when(wallet.walletId).thenAnswer((realInvocation) => "wallet id"); - mockito.when(wallet.coin).thenAnswer((realInvocation) => Coin.bitcoin); - mockito - .when(wallet.walletName) - .thenAnswer((realInvocation) => "wallet name"); - mockito.when(wallet.balance).thenAnswer( - (_) => Balance( - coin: Coin.bitcoin, - total: _a(0), - spendable: _a(0), - blockedTotal: _a(0), - pendingSpendable: _a(0), - ), - ); - - final wallets = MockWallets(); - final locale = MockLocaleService(); - final manager = Manager(wallet); - final managerProvider = ChangeNotifierProvider((ref) => manager); - - mockito - .when(wallets.getManagerProvider("wallet id")) - .thenAnswer((realInvocation) => managerProvider); - mockito.when(locale.locale).thenAnswer((_) => "en_US"); - - mockito - .when(wallets.getManagerProvider("wallet id")) - .thenAnswer((realInvocation) => managerProvider); - mockito - .when(wallets.getManager("wallet id")) - .thenAnswer((realInvocation) => manager); - - final navigator = mockingjay.MockNavigator(); - mockingjay - .when(() => navigator.pushNamed("/wallet", - arguments: Tuple2("wallet id", managerProvider))) - .thenAnswer((_) async => {}); - - await widgetTester.pumpWidget( - ProviderScope( - overrides: [ - walletsChangeNotifierProvider.overrideWithValue(wallets), - localeServiceChangeNotifierProvider.overrideWithValue(locale), - ], - child: MaterialApp( - theme: ThemeData( - extensions: [ - StackColors.fromStackColorTheme(LightColors()), - ], - ), - home: mockingjay.MockNavigatorProvider( - navigator: navigator, - child: const SimpleWalletCard( - walletId: "wallet id", - )), - ), - ), - ); - - await widgetTester.pumpAndSettle(); - - expect(find.byType(MaterialButton), findsOneWidget); - await widgetTester.tap(find.byType(MaterialButton)); - - await widgetTester.pumpAndSettle(); - }); - testWidgets('test widget loads correctly', (widgetTester) async { final CoinServiceAPI wallet = MockBitcoinWallet(); mockito.when(wallet.walletId).thenAnswer((realInvocation) => "wallet id"); @@ -108,7 +37,6 @@ void main() { .thenAnswer((realInvocation) => "wallet name"); mockito.when(wallet.balance).thenAnswer( (_) => Balance( - coin: Coin.bitcoin, total: _a(0), spendable: _a(0), blockedTotal: _a(0), diff --git a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.dart b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.dart index 70dfbfdc4..6f5c628b6 100644 --- a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.dart +++ b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.dart @@ -39,7 +39,6 @@ void main() { when(wallet.walletId).thenAnswer((_) => "some-wallet-id"); when(wallet.balance).thenAnswer( (_) => Balance( - coin: Coin.bitcoin, total: Amount.zero, spendable: Amount.zero, blockedTotal: Amount.zero, diff --git a/test/widget_tests/wallet_info_row/wallet_info_row_test.dart b/test/widget_tests/wallet_info_row/wallet_info_row_test.dart index a9318e11a..c6f53db75 100644 --- a/test/widget_tests/wallet_info_row/wallet_info_row_test.dart +++ b/test/widget_tests/wallet_info_row/wallet_info_row_test.dart @@ -39,7 +39,6 @@ void main() { when(wallet.walletId).thenAnswer((_) => "some-wallet-id"); when(wallet.balance).thenAnswer( (_) => Balance( - coin: Coin.bitcoin, total: Amount.zero, spendable: Amount.zero, blockedTotal: Amount.zero, From e72f2018d0a929af50c60a47ecfef59bbf35434d Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 11:20:57 -0600 Subject: [PATCH 13/14] missed firo amount --- lib/services/coins/firo/firo_wallet.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 24c5b0343..14ade1d40 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -704,6 +704,12 @@ Future isolateCreateJoinSplitTransaction( final txId = extTx.getId(); Logging.instance.log("txid $txId", level: LogLevel.Info); Logging.instance.log("txHex: $txHex", level: LogLevel.Info); + + final amountAmount = Amount( + rawValue: BigInt.from(amount), + fractionDigits: coin.decimals, + ); + return { "txid": txId, "txHex": txHex, @@ -720,11 +726,8 @@ Future isolateCreateJoinSplitTransaction( "height": locktime, "txType": "Sent", "confirmed_status": false, - "amount": Amount( - rawValue: BigInt.from(amount), - fractionDigits: coin.decimals, - ).decimal.toDouble(), - "recipientAmt": amount, + "amount": amountAmount.decimal.toDouble(), + "recipientAmt": amountAmount, "address": address, "timestamp": DateTime.now().millisecondsSinceEpoch ~/ 1000, "subType": "join", From 6eb9651fbbb9e9d17dc84bbbdd2c977100208d97 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 11 Apr 2023 11:52:19 -0600 Subject: [PATCH 14/14] desktop trade view layout fixes --- .../desktop_exchange_view.dart | 70 ++++++++++++++----- .../subwidgets/desktop_trade_history.dart | 32 +++------ 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart index e45f2d234..6c09ecd60 100644 --- a/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart +++ b/lib/pages_desktop_specific/desktop_exchange/desktop_exchange_view.dart @@ -8,11 +8,14 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'desktop_all_trades_view.dart'; + class DesktopExchangeView extends ConsumerStatefulWidget { const DesktopExchangeView({Key? key}) : super(key: key); @@ -106,36 +109,65 @@ class _DesktopExchangeViewState extends ConsumerState { right: 24, bottom: 24, ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + child: Column( children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( + Row( + children: [ + Expanded( + child: Text( "Exchange details", style: STextStyles.desktopTextExtraExtraSmall(context), ), - const SizedBox( - height: 16, + ), + const SizedBox( + width: 16, + ), + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Recent trades", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), + CustomTextButton( + text: "See all", + onTap: () { + Navigator.of(context).pushNamed( + DesktopAllTradesView.routeName, + ); + }, + ), + ], ), - const RoundedWhiteContainer( - padding: EdgeInsets.all(24), - child: ExchangeForm(), - ), - ], - ), + ), + ], ), const SizedBox( - width: 16, + height: 16, ), Expanded( child: Row( - children: const [ + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Expanded( + child: RoundedWhiteContainer( + padding: EdgeInsets.all(24), + child: ExchangeForm(), + ), + ), + const SizedBox( + width: 16, + ), Expanded( - child: DesktopTradeHistory(), + child: Row( + children: const [ + Expanded( + child: DesktopTradeHistory(), + ), + ], + ), ), ], ), diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart index a7dcca99f..707976425 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart @@ -5,7 +5,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; -import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_trades_view.dart'; import 'package:stackwallet/providers/exchange/trade_sent_from_stack_lookup_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; @@ -13,7 +12,6 @@ import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; -import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -65,35 +63,21 @@ class _DesktopTradeHistoryState extends ConsumerState { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Recent trades", - style: STextStyles.desktopTextExtraExtraSmall(context), - ), - CustomTextButton( - text: "See all", - onTap: () { - Navigator.of(context) - .pushNamed(DesktopAllTradesView.routeName); - }, - ), - ], - ), - const SizedBox( - height: 16, - ), Expanded( child: ListView.separated( shrinkWrap: true, primary: false, itemBuilder: (context, index) { BorderRadius? radius; - if (index == tradeCount - 1) { - radius = _borderRadiusLast; - } else if (index == 0) { + if (index == 0) { radius = _borderRadiusFirst; + if (tradeCount == 1) { + radius = BorderRadius.circular( + Constants.size.checkboxBorderRadius, + ); + } + } else if (index == tradeCount - 1) { + radius = _borderRadiusLast; } return Container(