From 140e68948f084a5435500e195712f3920f523409 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 08:26:03 -0600 Subject: [PATCH 01/11] uppercase tickers on exchange form coin select field buttons --- lib/widgets/textfields/exchange_textfield.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/widgets/textfields/exchange_textfield.dart b/lib/widgets/textfields/exchange_textfield.dart index 8d3c5d699..399d077c4 100644 --- a/lib/widgets/textfields/exchange_textfield.dart +++ b/lib/widgets/textfields/exchange_textfield.dart @@ -203,7 +203,7 @@ class _ExchangeTextFieldState extends State { width: 6, ), Text( - widget.ticker ?? "-", + widget.ticker?.toUpperCase() ?? "-", style: STextStyles.smallMed14(context).copyWith( color: Theme.of(context) .extension()! From d50e1e4a1418a4fd1f6b6d697e73ebaf370bb8a6 Mon Sep 17 00:00:00 2001 From: Diego Salazar Date: Tue, 22 Nov 2022 17:56:14 -0700 Subject: [PATCH 02/11] Bump version (1.5.18, build 90) --- pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index b1312427d..f79879f61 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.17+89 +version: 1.5.18+90 environment: sdk: ">=2.17.0 <3.0.0" @@ -410,4 +410,4 @@ import_sorter: ignored_files: # Optional, defaults to [] - \/test\/* - \/crypto_plugins\/* - - \/integration_test\/* \ No newline at end of file + - \/integration_test\/* From b3a7b19b8e9430dd7ad6dfb851ac09b2e64129e4 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 08:36:27 -0600 Subject: [PATCH 03/11] mobile exchange form layout fixes --- lib/pages/exchange_view/exchange_form.dart | 46 ++++++++++--------- .../sub_widgets/rate_type_toggle.dart | 4 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart index 921b35bf0..d818a73ff 100644 --- a/lib/pages/exchange_view/exchange_form.dart +++ b/lib/pages/exchange_view/exchange_form.dart @@ -1281,28 +1281,30 @@ class _ExchangeFormState extends ConsumerState { condition: isDesktop, builder: (child) => MouseRegion( cursor: SystemMouseCursors.click, - child: RoundedContainer( - padding: const EdgeInsets.all(6), - color: Theme.of(context) - .extension()! - .buttonBackSecondary, - radiusMultiplier: 0.75, - child: child, - ), + child: child, ), - child: GestureDetector( - onTap: () async { - await _swap(); - }, - child: Padding( - padding: const EdgeInsets.all(4), - child: SvgPicture.asset( - Assets.svg.swap, - width: 20, - height: 20, - color: Theme.of(context) - .extension()! - .accentColorDark, + child: RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(6) + : const EdgeInsets.all(2), + color: Theme.of(context) + .extension()! + .buttonBackSecondary, + radiusMultiplier: 0.75, + child: GestureDetector( + onTap: () async { + await _swap(); + }, + child: Padding( + padding: const EdgeInsets.all(4), + child: SvgPicture.asset( + Assets.svg.swap, + width: 20, + height: 20, + color: Theme.of(context) + .extension()! + .accentColorDark, + ), ), ), ), @@ -1310,7 +1312,7 @@ class _ExchangeFormState extends ConsumerState { ], ), SizedBox( - height: isDesktop ? 10 : 4, + height: isDesktop ? 10 : 7, ), ExchangeTextField( focusNode: _receiveFocusNode, diff --git a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart index 31ee01ce2..361d49e65 100644 --- a/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart +++ b/lib/pages/exchange_view/sub_widgets/rate_type_toggle.dart @@ -55,7 +55,7 @@ class RateTypeToggle extends ConsumerWidget { child: RoundedContainer( padding: isDesktop ? const EdgeInsets.all(17) - : const EdgeInsets.all(0), + : const EdgeInsets.all(12), color: estimated ? Theme.of(context) .extension()! @@ -136,7 +136,7 @@ class RateTypeToggle extends ConsumerWidget { child: RoundedContainer( padding: isDesktop ? const EdgeInsets.all(17) - : const EdgeInsets.all(0), + : const EdgeInsets.all(12), color: !estimated ? Theme.of(context) .extension()! From 4377c351d304d135303626f74ca7f175705ed2db Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 08:45:29 -0600 Subject: [PATCH 04/11] mobile exchange step 2 only enable next button when all fields are filled out --- .../exchange_step_views/step_2_view.dart | 95 +++++++++++++++---- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart index 800d1e146..030f91cb7 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart @@ -7,8 +7,6 @@ import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_3_view.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart'; -import 'package:stackwallet/providers/exchange/exchange_flow_is_active_state_provider.dart'; -import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/barcode_scanner_interface.dart'; @@ -20,6 +18,7 @@ import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/icon_widgets/addressbook_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart'; import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart'; @@ -57,6 +56,8 @@ class _Step2ViewState extends ConsumerState { late final FocusNode _toFocusNode; late final FocusNode _refundFocusNode; + bool enableNext = false; + bool isStackCoin(String ticker) { try { coinFromTickerCaseInsensitive(ticker); @@ -207,6 +208,12 @@ class _Step2ViewState extends ConsumerState { _toController.text = manager.walletName; model.recipientAddress = await manager .currentReceivingAddress; + + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController.text.isNotEmpty; + }); } }); } catch (e, s) { @@ -275,7 +282,12 @@ class _Step2ViewState extends ConsumerState { model.recipientAddress = _toController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); }, child: const XIcon(), ) @@ -295,7 +307,12 @@ class _Step2ViewState extends ConsumerState { model.recipientAddress = _toController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } }, child: _toController.text.isEmpty @@ -338,6 +355,12 @@ class _Step2ViewState extends ConsumerState { .state) .state = ""; } + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); }); }, child: const AddressBookIcon(), @@ -361,14 +384,24 @@ class _Step2ViewState extends ConsumerState { model.recipientAddress = _toController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } else { _toController.text = qrResult.rawContent; model.recipientAddress = _toController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } } on PlatformException catch (e, s) { Logging.instance.log( @@ -429,6 +462,11 @@ class _Step2ViewState extends ConsumerState { model.refundAddress = await manager .currentReceivingAddress; } + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController.text.isNotEmpty; + }); }); } catch (e, s) { Logging.instance @@ -495,7 +533,12 @@ class _Step2ViewState extends ConsumerState { model.refundAddress = _refundController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); }, child: const XIcon(), ) @@ -516,7 +559,12 @@ class _Step2ViewState extends ConsumerState { model.refundAddress = _refundController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } }, child: @@ -555,6 +603,12 @@ class _Step2ViewState extends ConsumerState { model.refundAddress = _refundController.text; } + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); }); }, child: const AddressBookIcon(), @@ -578,14 +632,24 @@ class _Step2ViewState extends ConsumerState { model.refundAddress = _refundController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } else { _refundController.text = qrResult.rawContent; model.refundAddress = _refundController.text; - setState(() {}); + setState(() { + enableNext = _toController + .text.isNotEmpty && + _refundController + .text.isNotEmpty; + }); } } on PlatformException catch (e, s) { Logging.instance.log( @@ -637,20 +701,15 @@ class _Step2ViewState extends ConsumerState { width: 16, ), Expanded( - child: TextButton( + child: PrimaryButton( + label: "Next", + enabled: enableNext, onPressed: () { Navigator.of(context).pushNamed( Step3View.routeName, arguments: model, ); }, - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonColor(context), - child: Text( - "Next", - style: STextStyles.button(context), - ), ), ), ], From 7011c6e1f68417d5e5fbee1ac53596bc50b618b0 Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Tue, 22 Nov 2022 12:31:45 -0700 Subject: [PATCH 05/11] submit on enter for wallet keys --- .../unlock_wallet_keys_desktop.dart | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart index 739a3ebc4..e6d0ff390 100644 --- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart +++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/unlock_wallet_keys_desktop.dart @@ -43,6 +43,58 @@ class _UnlockWalletKeysDesktopState bool continueEnabled = false; bool hidePassword = true; + Future enterPassphrase() async { + unawaited( + showDialog( + context: context, + builder: (context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + LoadingIndicator( + width: 200, + height: 200, + ), + ], + ), + ), + ); + + await Future.delayed(const Duration(seconds: 1)); + + final verified = await ref + .read(storageCryptoHandlerProvider) + .verifyPassphrase(passwordController.text); + + if (verified) { + Navigator.of(context, rootNavigator: true).pop(); + + final words = await ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .mnemonic; + + if (mounted) { + await Navigator.of(context).pushReplacementNamed( + WalletKeysDesktopPopup.routeName, + arguments: words, + ); + } + } else { + Navigator.of(context, rootNavigator: true).pop(); + + await Future.delayed(const Duration(milliseconds: 300)); + + unawaited( + showFloatingFlushBar( + type: FlushBarType.warning, + message: "Invalid passphrase!", + context: context, + ), + ); + } + } + @override void initState() { passwordController = TextEditingController(); @@ -120,6 +172,12 @@ class _UnlockWalletKeysDesktopState obscureText: hidePassword, enableSuggestions: false, autocorrect: false, + autofocus: true, + onSubmitted: (_) { + if (continueEnabled) { + enterPassphrase(); + } + }, decoration: standardInputDecoration( "Enter password", passwordFocusNode, From d7a7c706d2a066d6815088ba6228cdcd8fed2603 Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Wed, 23 Nov 2022 11:24:07 -0700 Subject: [PATCH 06/11] adjusted restore calendar height --- .../restore_options_view/restore_options_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart index 1ce5d713a..ac84964ca 100644 --- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart @@ -155,7 +155,7 @@ class _RestoreOptionsViewState extends ConsumerState { final date = await showRoundedDatePicker( context: context, initialDate: DateTime.now(), - height: height * 0.5, + height: height / 3.2, theme: ThemeData( primarySwatch: Util.createMaterialColor(fetchedColor), ), From adee71224b25bf9f8e72521dad0d289d55a16df1 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 12:31:31 -0600 Subject: [PATCH 07/11] Format coin amounts improvements, fixed fee rates display issue, use hard coded xmr estimates for now --- lib/models/paymint/transactions_model.dart | 10 +- .../confirm_change_now_send.dart | 46 ++++---- .../exchange_step_views/step_4_view.dart | 2 +- lib/pages/exchange_view/send_from_view.dart | 35 ++---- .../exchange_provider_options.dart | 31 ++++-- .../send_view/confirm_transaction_view.dart | 36 +++---- lib/pages/send_view/send_view.dart | 83 +++++++++----- .../transaction_fee_selection_sheet.dart | 77 +++++++++---- .../all_transactions_view.dart | 17 +-- .../transaction_details_view.dart | 58 +++++----- .../transaction_search_filter_view.dart | 19 +--- .../sub_widgets/desktop_fee_dropdown.dart | 86 ++++++++------- .../wallet_view/sub_widgets/desktop_send.dart | 24 +++-- .../coins/bitcoin/bitcoin_wallet.dart | 52 +++++---- .../coins/bitcoincash/bitcoincash_wallet.dart | 53 ++++----- .../coins/dogecoin/dogecoin_wallet.dart | 53 ++++----- lib/services/coins/firo/firo_wallet.dart | 81 +++++++------- .../coins/litecoin/litecoin_wallet.dart | 52 +++++---- lib/services/coins/monero/monero_wallet.dart | 101 +++++++++--------- .../coins/namecoin/namecoin_wallet.dart | 52 +++++---- .../coins/wownero/wownero_wallet.dart | 50 ++++----- lib/utilities/constants.dart | 42 ++++++-- lib/utilities/format.dart | 50 +++------ lib/widgets/transaction_card.dart | 18 +--- 24 files changed, 602 insertions(+), 526 deletions(-) diff --git a/lib/models/paymint/transactions_model.dart b/lib/models/paymint/transactions_model.dart index 08b6eb7e2..382459922 100644 --- a/lib/models/paymint/transactions_model.dart +++ b/lib/models/paymint/transactions_model.dart @@ -2,6 +2,7 @@ import 'package:dart_numerics/dart_numerics.dart'; import 'package:decimal/decimal.dart'; import 'package:hive/hive.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; part '../type_adaptors/transactions_model.g.dart'; @@ -220,14 +221,16 @@ class Transaction { (DateTime.now().millisecondsSinceEpoch ~/ 1000), txType: json['txType'] as String, amount: (Decimal.parse(json["amount"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(Coin + .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure .toBigInt() .toInt(), aliens: [], worthNow: json['worthNow'] as String, worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0", fees: (Decimal.parse(json["fees"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(Coin + .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure .toBigInt() .toInt(), inputSize: json['inputSize'] as int? ?? 0, @@ -386,7 +389,8 @@ class Output { scriptpubkeyType: json['scriptPubKey']['type'] as String?, scriptpubkeyAddress: address, value: (Decimal.parse(json["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(Coin + .firo))) // dirty hack but we need 8 decimal places here to keep consistent data structure .toBigInt() .toInt(), ); diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart index 540067915..0e1eef755 100644 --- a/lib/pages/exchange_view/confirm_change_now_send.dart +++ b/lib/pages/exchange_view/confirm_change_now_send.dart @@ -342,6 +342,9 @@ class _ConfirmChangeNowSendViewState localeServiceChangeNotifierProvider .select((value) => value.locale), ), + ref.watch( + managerProvider.select((value) => value.coin), + ), )} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", @@ -382,6 +385,9 @@ class _ConfirmChangeNowSendViewState localeServiceChangeNotifierProvider .select((value) => value.locale), ), + ref.watch( + managerProvider.select((value) => value.coin), + ), )} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", @@ -563,13 +569,12 @@ class _ConfirmChangeNowSendViewState ], ), child: Text( - "${Format.satoshiAmountToPrettyString( - transactionInfo["recipientAmt"] as int, - ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - )} ${ref.watch( + "${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale), + ), ref.watch( + managerProvider.select((value) => value.coin), + ))} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", style: STextStyles.itemSubtitle12(context), @@ -597,13 +602,12 @@ class _ConfirmChangeNowSendViewState style: STextStyles.smallMed12(context), ), Text( - "${Format.satoshiAmountToPrettyString( - transactionInfo["fee"] as int, - ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - )} ${ref.watch( + "${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale), + ), ref.watch( + managerProvider.select((value) => value.coin), + ))} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", style: STextStyles.itemSubtitle12(context), @@ -685,14 +689,12 @@ class _ConfirmChangeNowSendViewState ), ), Text( - "${Format.satoshiAmountToPrettyString( - (transactionInfo["fee"] as int) + - (transactionInfo["recipientAmt"] as int), - ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - )} ${ref.watch( + "${Format.satoshiAmountToPrettyString((transactionInfo["fee"] as int) + (transactionInfo["recipientAmt"] as int), ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale), + ), ref.watch( + managerProvider.select((value) => value.coin), + ))} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", style: STextStyles.itemSubtitle12(context).copyWith( diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart index a8b403dcf..f5975a277 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart @@ -487,7 +487,7 @@ class _Step4ViewState extends ConsumerState { final amount = Format.decimalAmountToSatoshis( - model.sendAmount); + model.sendAmount, manager.coin); final address = model.trade!.payInAddress; diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart index 7c5f5541c..f13971a67 100644 --- a/lib/pages/exchange_view/send_from_view.dart +++ b/lib/pages/exchange_view/send_from_view.dart @@ -61,25 +61,7 @@ class _SendFromViewState extends ConsumerState { late final Trade trade; String formatAmount(Decimal amount, Coin coin) { - switch (coin) { - case Coin.bitcoin: - case Coin.bitcoincash: - case Coin.litecoin: - case Coin.dogecoin: - case Coin.epicCash: - case Coin.firo: - case Coin.namecoin: - case Coin.bitcoinTestNet: - case Coin.litecoinTestNet: - case Coin.bitcoincashTestnet: - case Coin.dogecoinTestNet: - case Coin.firoTestNet: - return amount.toStringAsFixed(Constants.decimalPlaces); - case Coin.monero: - return amount.toStringAsFixed(Constants.decimalPlacesMonero); - case Coin.wownero: - return amount.toStringAsFixed(Constants.decimalPlacesWownero); - } + return amount.toStringAsFixed(Constants.decimalPlacesForCoin(coin)); } @override @@ -233,7 +215,7 @@ class _SendFromCardState extends ConsumerState { late final Trade trade; Future _send(Manager manager, {bool? shouldSendPublicFiroFunds}) async { - final _amount = Format.decimalAmountToSatoshis(amount); + final _amount = Format.decimalAmountToSatoshis(amount, manager.coin); try { bool wasCancelled = false; @@ -464,7 +446,8 @@ class _SendFromCardState extends ConsumerState { "${Format.localizedStringAsFixed( value: snapshot.data!, locale: locale, - decimalPlaces: Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin(coin), )} ${coin.ticker}", style: STextStyles.itemSubtitle(context), ); @@ -549,7 +532,8 @@ class _SendFromCardState extends ConsumerState { "${Format.localizedStringAsFixed( value: snapshot.data!, locale: locale, - decimalPlaces: Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin(coin), )} ${coin.ticker}", style: STextStyles.itemSubtitle(context), ); @@ -657,11 +641,8 @@ class _SendFromCardState extends ConsumerState { "${Format.localizedStringAsFixed( value: snapshot.data!, locale: locale, - decimalPlaces: coin == Coin.monero - ? Constants.decimalPlacesMonero - : coin == Coin.wownero - ? Constants.decimalPlacesWownero - : Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin(coin), )} ${coin.ticker}", style: STextStyles.itemSubtitle(context), ); diff --git a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart index 4dd768403..ebaf68066 100644 --- a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart +++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart @@ -159,6 +159,14 @@ class ExchangeProviderOptions extends ConsumerWidget { .toDecimal( scaleOnInfinitePrecision: 12); } + Coin coin; + try { + coin = + coinFromTickerCaseInsensitive(to!); + } catch (_) { + coin = Coin.bitcoin; + } + return Text( "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed( value: rate, @@ -167,11 +175,9 @@ class ExchangeProviderOptions extends ConsumerWidget { .select( (value) => value.locale), ), - decimalPlaces: to!.toUpperCase() == - Coin.monero.ticker - .toUpperCase() - ? Constants.decimalPlacesMonero - : Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin( + coin), )} ${to!.toUpperCase()}", style: STextStyles.itemSubtitle12(context) @@ -354,6 +360,13 @@ class ExchangeProviderOptions extends ConsumerWidget { .toDecimal( scaleOnInfinitePrecision: 12); + Coin coin; + try { + coin = + coinFromTickerCaseInsensitive(to!); + } catch (_) { + coin = Coin.bitcoin; + } return Text( "1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed( value: rate, @@ -362,11 +375,9 @@ class ExchangeProviderOptions extends ConsumerWidget { .select( (value) => value.locale), ), - decimalPlaces: to!.toUpperCase() == - Coin.monero.ticker - .toUpperCase() - ? Constants.decimalPlacesMonero - : Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin( + coin), )} ${to!.toUpperCase()}", style: STextStyles.itemSubtitle12(context) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 276203804..1ddeb3c9f 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -317,13 +317,12 @@ class _ConfirmTransactionViewState style: STextStyles.smallMed12(context), ), Text( - "${Format.satoshiAmountToPrettyString( - transactionInfo["recipientAmt"] as int, - ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - )} ${ref.watch( + "${Format.satoshiAmountToPrettyString(transactionInfo["recipientAmt"] as int, ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale), + ), ref.watch( + managerProvider.select((value) => value.coin), + ))} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", style: STextStyles.itemSubtitle12(context), @@ -344,13 +343,12 @@ class _ConfirmTransactionViewState style: STextStyles.smallMed12(context), ), Text( - "${Format.satoshiAmountToPrettyString( - transactionInfo["fee"] as int, - ref.watch( - localeServiceChangeNotifierProvider - .select((value) => value.locale), - ), - )} ${ref.watch( + "${Format.satoshiAmountToPrettyString(transactionInfo["fee"] as int, ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale), + ), ref.watch( + managerProvider.select((value) => value.coin), + ))} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", style: STextStyles.itemSubtitle12(context), @@ -494,6 +492,7 @@ class _ConfirmTransactionViewState localeServiceChangeNotifierProvider .select((value) => value.locale), ), + coin, )} ${coin.ticker}", style: STextStyles .desktopTextExtraExtraSmall( @@ -638,11 +637,7 @@ class _ConfirmTransactionViewState value: fee, locale: ref.watch(localeServiceChangeNotifierProvider .select((value) => value.locale)), - decimalPlaces: coin == Coin.monero - ? Constants.decimalPlacesMonero - : coin == Coin.wownero - ? Constants.decimalPlacesWownero - : Constants.decimalPlaces, + decimalPlaces: Constants.decimalPlacesForCoin(coin), )} ${coin.ticker}", style: STextStyles.itemSubtitle(context), ); @@ -750,6 +745,9 @@ class _ConfirmTransactionViewState localeServiceChangeNotifierProvider .select((value) => value.locale), ), + ref.watch( + managerProvider.select((value) => value.coin), + ), )} ${ref.watch( managerProvider.select((value) => value.coin), ).ticker}", diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index d91b7a3ea..2539b89ab 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:cw_core/monero_transaction_priority.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -30,6 +31,7 @@ import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.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/animated_text.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; @@ -41,8 +43,6 @@ import 'package:stackwallet/widgets/stack_dialog.dart'; import 'package:stackwallet/widgets/stack_text_field.dart'; import 'package:stackwallet/widgets/textfield_icon_button.dart'; -import 'package:stackwallet/utilities/util.dart'; - class SendView extends ConsumerStatefulWidget { const SendView({ Key? key, @@ -211,29 +211,47 @@ class _SendViewState extends ConsumerState { } int fee; + if (coin == Coin.monero) { + MoneroTransactionPriority specialMoneroId; + switch (ref.read(feeRateTypeStateProvider.state).state) { + case FeeRateType.fast: + specialMoneroId = MoneroTransactionPriority.fast; + break; + case FeeRateType.average: + specialMoneroId = MoneroTransactionPriority.regular; + break; + case FeeRateType.slow: + specialMoneroId = MoneroTransactionPriority.slow; + break; + } - if (coin == Coin.firo || coin == Coin.firoTestNet) { + fee = await manager.estimateFeeFor(amount, specialMoneroId.raw!); + cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin) + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); + + return cachedFees[amount]!; + } else if (coin == Coin.firo || coin == Coin.firoTestNet) { if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private") { fee = await manager.estimateFeeFor(amount, feeRate); - cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee) - .toStringAsFixed(Constants.decimalPlaces); + cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee, coin: coin) + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); return cachedFiroPrivateFees[amount]!; } else { fee = await (manager.wallet as FiroWallet) .estimateFeeForPublic(amount, feeRate); - cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee) - .toStringAsFixed(Constants.decimalPlaces); + cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee, coin: coin) + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); return cachedFiroPublicFees[amount]!; } } else { fee = await manager.estimateFeeFor(amount, feeRate); - cachedFees[amount] = - Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces); + cachedFees[amount] = Format.satoshisToAmount(fee, coin: coin) + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); return cachedFees[amount]!; } @@ -296,8 +314,8 @@ class _SendViewState extends ConsumerState { }); } else { setState(() { - _calculateFeesFuture = - calculateFees(Format.decimalAmountToSatoshis(_amountToSend!)); + _calculateFeesFuture = calculateFees( + Format.decimalAmountToSatoshis(_amountToSend!, coin)); }); } } @@ -311,8 +329,8 @@ class _SendViewState extends ConsumerState { }); } else { setState(() { - _calculateFeesFuture = - calculateFees(Format.decimalAmountToSatoshis(_amountToSend!)); + _calculateFeesFuture = calculateFees( + Format.decimalAmountToSatoshis(_amountToSend!, coin)); }); } } @@ -354,8 +372,8 @@ class _SendViewState extends ConsumerState { }); } else { setState(() { - _calculateFeesFuture = - calculateFees(Format.decimalAmountToSatoshis(_amountToSend!)); + _calculateFeesFuture = calculateFees( + Format.decimalAmountToSatoshis(_amountToSend!, coin)); }); } }); @@ -492,7 +510,9 @@ class _SendViewState extends ConsumerState { onTap: () { cryptoAmountController.text = _cachedBalance!.toStringAsFixed( - Constants.decimalPlaces); + Constants + .decimalPlacesForCoin( + coin)); }, child: Container( color: Colors.transparent, @@ -781,8 +801,9 @@ class _SendViewState extends ConsumerState { .read( localeServiceChangeNotifierProvider) .locale, - decimalPlaces: - Constants.decimalPlaces, + decimalPlaces: Constants + .decimalPlacesForCoin( + coin), ); amount.toString(); _amountToSend = amount; @@ -1044,19 +1065,22 @@ class _SendViewState extends ConsumerState { (await firoWallet .availablePrivateBalance()) .toStringAsFixed( - Constants.decimalPlaces); + Constants.decimalPlacesForCoin( + coin)); } else { cryptoAmountController.text = (await firoWallet .availablePublicBalance()) .toStringAsFixed( - Constants.decimalPlaces); + Constants.decimalPlacesForCoin( + coin)); } } else { cryptoAmountController.text = (await ref .read(provider) .availableBalance) - .toStringAsFixed(Constants.decimalPlaces); + .toStringAsFixed( + Constants.decimalPlacesForCoin(coin)); } }, ), @@ -1167,7 +1191,8 @@ class _SendViewState extends ConsumerState { ? Decimal.zero : (baseAmount / _price).toDecimal( scaleOnInfinitePrecision: - Constants.decimalPlaces); + Constants.decimalPlacesForCoin( + coin)); } if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) { @@ -1184,7 +1209,8 @@ class _SendViewState extends ConsumerState { locale: ref .read(localeServiceChangeNotifierProvider) .locale, - decimalPlaces: Constants.decimalPlaces, + decimalPlaces: + Constants.decimalPlacesForCoin(coin), ); _cryptoAmountChangeLock = true; @@ -1506,7 +1532,7 @@ class _SendViewState extends ConsumerState { } final amount = Format.decimalAmountToSatoshis( - _amountToSend!); + _amountToSend!, coin); int availableBalance; if ((coin == Coin.firo || coin == Coin.firoTestNet)) { @@ -1520,18 +1546,21 @@ class _SendViewState extends ConsumerState { Format.decimalAmountToSatoshis( await (manager.wallet as FiroWallet) - .availablePrivateBalance()); + .availablePrivateBalance(), + coin); } else { availableBalance = Format.decimalAmountToSatoshis( await (manager.wallet as FiroWallet) - .availablePublicBalance()); + .availablePublicBalance(), + coin); } } else { availableBalance = Format.decimalAmountToSatoshis( - await manager.availableBalance); + await manager.availableBalance, + coin); } // confirm send all diff --git a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart index 982086d3c..2f5ce2f3e 100644 --- a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart +++ b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/monero_transaction_priority.dart'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -70,16 +71,27 @@ class _TransactionFeeSelectionSheetState final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.fast.raw!); + ref.read(feeSheetSessionCacheProvider).fast[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).fast[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).fast[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).fast[amount]!; @@ -88,17 +100,27 @@ class _TransactionFeeSelectionSheetState if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.regular.raw!); + ref.read(feeSheetSessionCacheProvider).average[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).average[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).average[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).average[amount]!; @@ -107,17 +129,27 @@ class _TransactionFeeSelectionSheetState if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.slow.raw!); + ref.read(feeSheetSessionCacheProvider).slow[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).slow[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).slow[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).slow[amount]!; @@ -225,7 +257,7 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.fast; } - String? fee = getAmount(FeeRateType.fast); + String? fee = getAmount(FeeRateType.fast, manager.coin); if (fee != null) { widget.updateChosen(fee); } @@ -293,7 +325,7 @@ class _TransactionFeeSelectionSheetState feeRate: feeObject!.fast, amount: Format .decimalAmountToSatoshis( - amount)), + amount, manager.coin)), // future: manager.estimateFeeFor( // Format.decimalAmountToSatoshis( // amount), @@ -358,7 +390,8 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.average; } - String? fee = getAmount(FeeRateType.average); + String? fee = + getAmount(FeeRateType.average, manager.coin); if (fee != null) { widget.updateChosen(fee); } @@ -424,7 +457,7 @@ class _TransactionFeeSelectionSheetState feeRate: feeObject!.medium, amount: Format .decimalAmountToSatoshis( - amount)), + amount, manager.coin)), // future: manager.estimateFeeFor( // Format.decimalAmountToSatoshis( // amount), @@ -489,7 +522,7 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.slow; } - String? fee = getAmount(FeeRateType.slow); + String? fee = getAmount(FeeRateType.slow, manager.coin); print("fee $fee"); if (fee != null) { widget.updateChosen(fee); @@ -557,7 +590,7 @@ class _TransactionFeeSelectionSheetState feeRate: feeObject!.slow, amount: Format .decimalAmountToSatoshis( - amount)), + amount, manager.coin)), // future: manager.estimateFeeFor( // Format.decimalAmountToSatoshis( // amount), @@ -624,10 +657,10 @@ class _TransactionFeeSelectionSheetState ); } - String? getAmount(FeeRateType feeRateType) { + String? getAmount(FeeRateType feeRateType, Coin coin) { try { print(feeRateType); - var amount = Format.decimalAmountToSatoshis(this.amount); + var amount = Format.decimalAmountToSatoshis(this.amount, coin); print(amount); print(ref.read(feeSheetSessionCacheProvider).fast); print(ref.read(feeSheetSessionCacheProvider).average); diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 95dcc8126..b9ea02e79 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -937,13 +937,9 @@ class _DesktopTransactionCardRowState flex: 6, child: Builder( builder: (_) { - final amount = coin == Coin.monero - ? (_transaction.amount ~/ 10000) - : coin == Coin.wownero - ? (_transaction.amount ~/ 1000) - : _transaction.amount; + final amount = _transaction.amount; return Text( - "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}", + "$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}", style: STextStyles.desktopTextExtraExtraSmall(context) .copyWith( color: Theme.of(context) @@ -960,17 +956,12 @@ class _DesktopTransactionCardRowState flex: 4, child: Builder( builder: (_) { - // TODO: modify Format. to take optional Coin parameter so this type oif check isn't done in ui int value = _transaction.amount; - if (coin == Coin.monero) { - value = (value ~/ 10000); - } else if (coin == Coin.wownero) { - value = (value ~/ 1000); - } return Text( "$prefix${Format.localizedStringAsFixed( - value: Format.satoshisToAmount(value) * price, + value: Format.satoshisToAmount(value, coin: coin) * + price, locale: locale, decimalPlaces: 2, )} $baseCurrency", diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index 4d45428ff..c2a0590e4 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -78,8 +78,8 @@ class _TransactionDetailsViewState walletId = widget.walletId; coin = widget.coin; - amount = Format.satoshisToAmount(_transaction.amount); - fee = Format.satoshisToAmount(_transaction.fees); + amount = Format.satoshisToAmount(_transaction.amount, coin: coin); + fee = Format.satoshisToAmount(_transaction.fees, coin: coin); if ((coin == Coin.firo || coin == Coin.firoTestNet) && _transaction.subType == "mint") { @@ -418,21 +418,15 @@ class _TransactionDetailsViewState children: [ SelectableText( "$amountPrefix${Format.localizedStringAsFixed( - value: coin == Coin.monero - ? (amount / 10000.toDecimal()) - .toDecimal() - : coin == Coin.wownero - ? (amount / - 1000.toDecimal()) - .toDecimal() - : amount, + value: amount, locale: ref.watch( localeServiceChangeNotifierProvider .select( (value) => value.locale), ), decimalPlaces: - Constants.decimalPlaces, + Constants.decimalPlacesForCoin( + coin), )} ${coin.ticker}", style: isDesktop ? STextStyles @@ -454,11 +448,21 @@ class _TransactionDetailsViewState (value) => value.externalCalls))) SelectableText( - "$amountPrefix${Format.localizedStringAsFixed(value: (coin == Coin.monero ? (amount / 10000.toDecimal()).toDecimal() : coin == Coin.wownero ? (amount / 1000.toDecimal()).toDecimal() : amount) * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1)), locale: ref.watch( - localeServiceChangeNotifierProvider - .select((value) => - value.locale), - ), decimalPlaces: 2)} ${ref.watch( + "$amountPrefix${Format.localizedStringAsFixed( + value: amount * + ref.watch( + priceAnd24hChangeNotifierProvider + .select((value) => value + .getPrice(coin) + .item1), + ), + locale: ref.watch( + localeServiceChangeNotifierProvider + .select((value) => + value.locale), + ), + decimalPlaces: 2, + )} ${ref.watch( prefsChangeNotifierProvider .select( (value) => value.currency, @@ -834,32 +838,22 @@ class _TransactionDetailsViewState final feeString = showFeePending ? _transaction.confirmedStatus ? Format.localizedStringAsFixed( - value: coin == Coin.monero - ? (fee / 10000.toDecimal()) - .toDecimal() - : coin == Coin.wownero - ? (fee / 1000.toDecimal()) - .toDecimal() - : fee, + value: fee, locale: ref.watch( localeServiceChangeNotifierProvider .select( (value) => value.locale)), decimalPlaces: - Constants.decimalPlaces) + Constants.decimalPlacesForCoin( + coin)) : "Pending" : Format.localizedStringAsFixed( - value: coin == Coin.monero - ? (fee / 10000.toDecimal()) - .toDecimal() - : coin == Coin.wownero - ? (fee / 1000.toDecimal()) - .toDecimal() - : fee, + value: fee, locale: ref.watch( localeServiceChangeNotifierProvider .select((value) => value.locale)), - decimalPlaces: Constants.decimalPlaces); + decimalPlaces: + Constants.decimalPlacesForCoin(coin)); return Row( mainAxisAlignment: diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart index d135ea276..0b3fd3acb 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart @@ -79,7 +79,7 @@ class _TransactionSearchViewState String amount = ""; if (filterState.amount != null) { amount = Format.satoshiAmountToPrettyString(filterState.amount!, - ref.read(localeServiceChangeNotifierProvider).locale); + ref.read(localeServiceChangeNotifierProvider).locale, widget.coin); } _amountTextEditingController.text = amount; } @@ -967,22 +967,7 @@ class _TransactionSearchViewState } int? amount; if (amountDecimal != null) { - if (widget.coin == Coin.monero) { - amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinMonero)) - .floor() - .toBigInt() - .toInt(); - } else if (widget.coin == Coin.wownero) { - amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoinWownero)) - .floor() - .toBigInt() - .toInt(); - } else { - amount = (amountDecimal * Decimal.fromInt(Constants.satsPerCoin)) - .floor() - .toBigInt() - .toInt(); - } + amount = Format.decimalAmountToSatoshis(amountDecimal, widget.coin); } final TransactionFilter filter = TransactionFilter( diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart index 9acb3a6f9..25e1f47ab 100644 --- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart +++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart @@ -1,3 +1,4 @@ +import 'package:cw_core/monero_transaction_priority.dart'; import 'package:decimal/decimal.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; @@ -55,16 +56,27 @@ class _DesktopFeeDropDownState extends ConsumerState { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.fast.raw!); + ref.read(feeSheetSessionCacheProvider).fast[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).fast[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).fast[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).fast[amount]!; @@ -74,16 +86,27 @@ class _DesktopFeeDropDownState extends ConsumerState { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.regular.raw!); + ref.read(feeSheetSessionCacheProvider).average[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).average[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).average[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).average[amount]!; @@ -93,47 +116,33 @@ class _DesktopFeeDropDownState extends ConsumerState { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (coin == Coin.monero || coin == Coin.wownero) { + final fee = await manager.estimateFeeFor( + amount, MoneroTransactionPriority.slow.raw!); + ref.read(feeSheetSessionCacheProvider).slow[amount] = + Format.satoshisToAmount( + fee, + coin: coin, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { ref.read(feeSheetSessionCacheProvider).slow[amount] = - Format.satoshisToAmount(await (manager.wallet as FiroWallet) - .estimateFeeForPublic(amount, feeRate)); + Format.satoshisToAmount( + await (manager.wallet as FiroWallet) + .estimateFeeForPublic(amount, feeRate), + coin: coin); } else { ref.read(feeSheetSessionCacheProvider).slow[amount] = Format.satoshisToAmount( - await manager.estimateFeeFor(amount, feeRate)); + await manager.estimateFeeFor(amount, feeRate), + coin: coin); } } return ref.read(feeSheetSessionCacheProvider).slow[amount]!; } } - String estimatedTimeToBeIncludedInNextBlock( - int targetBlockTime, int estimatedNumberOfBlocks) { - int time = targetBlockTime * estimatedNumberOfBlocks; - - int hours = (time / 3600).floor(); - if (hours > 1) { - return "~$hours hours"; - } else if (hours == 1) { - return "~$hours hour"; - } - - // less than an hour - - final string = (time / 60).toStringAsFixed(1); - - if (string == "1.0") { - return "~1 minute"; - } else { - if (string.endsWith(".0")) { - return "~${(time / 60).floor()} minutes"; - } - return "~$string minutes"; - } - } - @override void initState() { walletId = widget.walletId; @@ -307,7 +316,7 @@ class FeeDropDownChild extends ConsumerWidget { return FutureBuilder( future: feeFor( coin: manager.coin, - feeRateType: FeeRateType.fast, + feeRateType: feeRateType, feeRate: feeRateType == FeeRateType.fast ? feeObject!.fast : feeRateType == FeeRateType.slow @@ -315,6 +324,7 @@ class FeeDropDownChild extends ConsumerWidget { : feeObject!.medium, amount: Format.decimalAmountToSatoshis( ref.watch(sendAmountProvider.state).state, + manager.coin, ), ), builder: (_, AsyncSnapshot snapshot) { diff --git a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart index 336dd7b4e..72690c7e5 100644 --- a/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart +++ b/lib/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/desktop_send.dart @@ -161,20 +161,22 @@ class _DesktopSendState extends ConsumerState { return; } - final amount = Format.decimalAmountToSatoshis(_amountToSend!); + final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin); int availableBalance; if ((coin == Coin.firo || coin == Coin.firoTestNet)) { if (ref.read(publicPrivateBalanceStateProvider.state).state == "Private") { availableBalance = Format.decimalAmountToSatoshis( - await (manager.wallet as FiroWallet).availablePrivateBalance()); + await (manager.wallet as FiroWallet).availablePrivateBalance(), + coin); } else { availableBalance = Format.decimalAmountToSatoshis( - await (manager.wallet as FiroWallet).availablePublicBalance()); + await (manager.wallet as FiroWallet).availablePublicBalance(), + coin); } } else { availableBalance = - Format.decimalAmountToSatoshis(await manager.availableBalance); + Format.decimalAmountToSatoshis(await manager.availableBalance, coin); } // confirm send all @@ -642,7 +644,7 @@ class _DesktopSendState extends ConsumerState { cryptoAmountController.text = Format.localizedStringAsFixed( value: amount, locale: ref.read(localeServiceChangeNotifierProvider).locale, - decimalPlaces: Constants.decimalPlaces, + decimalPlaces: Constants.decimalPlacesForCoin(coin), ); amount.toString(); _amountToSend = amount; @@ -709,8 +711,8 @@ class _DesktopSendState extends ConsumerState { } else { _amountToSend = baseAmount <= Decimal.zero ? Decimal.zero - : (baseAmount / _price) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces); + : (baseAmount / _price).toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)); } if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) { return; @@ -722,7 +724,7 @@ class _DesktopSendState extends ConsumerState { final amountString = Format.localizedStringAsFixed( value: _amountToSend!, locale: ref.read(localeServiceChangeNotifierProvider).locale, - decimalPlaces: Constants.decimalPlaces, + decimalPlaces: Constants.decimalPlacesForCoin(coin), ); _cryptoAmountChangeLock = true; @@ -752,18 +754,18 @@ class _DesktopSendState extends ConsumerState { "Private") { cryptoAmountController.text = (await firoWallet.availablePrivateBalance()) - .toStringAsFixed(Constants.decimalPlaces); + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); } else { cryptoAmountController.text = (await firoWallet.availablePublicBalance()) - .toStringAsFixed(Constants.decimalPlaces); + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); } } else { cryptoAmountController.text = (await ref .read(walletsChangeNotifierProvider) .getManager(walletId) .availableBalance) - .toStringAsFixed(Constants.decimalPlaces); + .toStringAsFixed(Constants.decimalPlacesForCoin(coin)); } } diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index dfd5ea180..25ec6b519 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -200,19 +200,21 @@ class BitcoinWallet extends CoinServiceAPI { Future get availableBalance async { final data = await utxoData; return Format.satoshisToAmount( - data.satoshiBalance - data.satoshiBalanceUnconfirmed); + data.satoshiBalance - data.satoshiBalanceUnconfirmed, + coin: coin); } @override Future get pendingBalance async { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed); + return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin); } @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -222,13 +224,13 @@ class BitcoinWallet extends CoinServiceAPI { .get(boxName: walletId, key: 'totalBalance') as int?; if (totalBalance == null) { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } else { - return Format.satoshisToAmount(totalBalance); + return Format.satoshisToAmount(totalBalance, coin: coin); } } final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } @override @@ -266,7 +268,8 @@ class BitcoinWallet extends CoinServiceAPI { @override Future get maxFee async { final fee = (await fees).fast as String; - final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin); + final satsFee = + Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin)); return satsFee.floor().toBigInt().toInt(); } @@ -1093,7 +1096,8 @@ class BitcoinWallet extends CoinServiceAPI { // check for send all bool isSendAll = false; - final balance = Format.decimalAmountToSatoshis(await availableBalance); + final balance = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1297,7 +1301,7 @@ class BitcoinWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1497,9 +1501,9 @@ class BitcoinWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -1968,7 +1972,7 @@ class BitcoinWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -1978,15 +1982,16 @@ class BitcoinWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -2532,7 +2537,7 @@ class BitcoinWallet extends CoinServiceAPI { if (prevOut == out["n"]) { inputAmtSentFromWallet += (Decimal.parse(out["value"]!.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2545,7 +2550,7 @@ class BitcoinWallet extends CoinServiceAPI { final String address = output["scriptPubKey"]!["address"] as String; final value = output["value"]!; final _value = (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOutput += _value; @@ -2570,7 +2575,7 @@ class BitcoinWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["address"]; if (address != null) { final value = (Decimal.parse(output["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOut += value; @@ -2593,7 +2598,7 @@ class BitcoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { totalIn += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2615,7 +2620,7 @@ class BitcoinWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -2625,7 +2630,7 @@ class BitcoinWallet extends CoinServiceAPI { midSortedTx["amount"] = outputAmtAddressedToWallet; final worthNow = ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -3753,7 +3758,8 @@ class BitcoinWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - final available = Format.decimalAmountToSatoshis(await availableBalance); + final available = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 429af898e..59b2454b4 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -170,19 +170,21 @@ class BitcoinCashWallet extends CoinServiceAPI { Future get availableBalance async { final data = await utxoData; return Format.satoshisToAmount( - data.satoshiBalance - data.satoshiBalanceUnconfirmed); + data.satoshiBalance - data.satoshiBalanceUnconfirmed, + coin: coin); } @override Future get pendingBalance async { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed); + return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin); } @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -192,13 +194,13 @@ class BitcoinCashWallet extends CoinServiceAPI { .get(boxName: walletId, key: 'totalBalance') as int?; if (totalBalance == null) { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } else { - return Format.satoshisToAmount(totalBalance); + return Format.satoshisToAmount(totalBalance, coin: coin); } } final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } @override @@ -232,8 +234,8 @@ class BitcoinCashWallet extends CoinServiceAPI { @override Future get maxFee async { final fee = (await fees).fast; - final satsFee = - Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin); + final satsFee = Format.satoshisToAmount(fee, coin: coin) * + Decimal.fromInt(Constants.satsPerCoin(coin)); return satsFee.floor().toBigInt().toInt(); } @@ -988,7 +990,8 @@ class BitcoinCashWallet extends CoinServiceAPI { } // check for send all bool isSendAll = false; - final balance = Format.decimalAmountToSatoshis(await availableBalance); + final balance = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1175,7 +1178,7 @@ class BitcoinCashWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1384,9 +1387,9 @@ class BitcoinCashWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -1791,7 +1794,7 @@ class BitcoinCashWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -1801,15 +1804,16 @@ class BitcoinCashWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -2332,7 +2336,7 @@ class BitcoinCashWallet extends CoinServiceAPI { if (prevOut == out["n"]) { inputAmtSentFromWallet += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2345,7 +2349,7 @@ class BitcoinCashWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["addresses"][0]; final value = output["value"]; final _value = (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOutput += _value; @@ -2370,7 +2374,7 @@ class BitcoinCashWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["addresses"][0]; if (address != null) { final value = (Decimal.parse(output["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOut += value; @@ -2394,7 +2398,7 @@ class BitcoinCashWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { totalIn += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2416,7 +2420,7 @@ class BitcoinCashWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -2426,7 +2430,7 @@ class BitcoinCashWallet extends CoinServiceAPI { midSortedTx["amount"] = outputAmtAddressedToWallet; final worthNow = ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -3457,7 +3461,8 @@ class BitcoinCashWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - final available = Format.decimalAmountToSatoshis(await availableBalance); + final available = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/dogecoin/dogecoin_wallet.dart b/lib/services/coins/dogecoin/dogecoin_wallet.dart index 41778a9e0..f7372752b 100644 --- a/lib/services/coins/dogecoin/dogecoin_wallet.dart +++ b/lib/services/coins/dogecoin/dogecoin_wallet.dart @@ -167,19 +167,21 @@ class DogecoinWallet extends CoinServiceAPI { Future get availableBalance async { final data = await utxoData; return Format.satoshisToAmount( - data.satoshiBalance - data.satoshiBalanceUnconfirmed); + data.satoshiBalance - data.satoshiBalanceUnconfirmed, + coin: coin); } @override Future get pendingBalance async { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed); + return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin); } @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -189,13 +191,13 @@ class DogecoinWallet extends CoinServiceAPI { .get(boxName: walletId, key: 'totalBalance') as int?; if (totalBalance == null) { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } else { - return Format.satoshisToAmount(totalBalance); + return Format.satoshisToAmount(totalBalance, coin: coin); } } final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } @override @@ -225,8 +227,8 @@ class DogecoinWallet extends CoinServiceAPI { @override Future get maxFee async { final fee = (await fees).fast; - final satsFee = - Format.satoshisToAmount(fee) * Decimal.fromInt(Constants.satsPerCoin); + final satsFee = Format.satoshisToAmount(fee, coin: coin) * + Decimal.fromInt(Constants.satsPerCoin(coin)); return satsFee.floor().toBigInt().toInt(); } @@ -878,7 +880,8 @@ class DogecoinWallet extends CoinServiceAPI { } // check for send all bool isSendAll = false; - final balance = Format.decimalAmountToSatoshis(await availableBalance); + final balance = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1065,7 +1068,7 @@ class DogecoinWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1247,9 +1250,9 @@ class DogecoinWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -1650,7 +1653,7 @@ class DogecoinWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -1660,15 +1663,16 @@ class DogecoinWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -2144,7 +2148,7 @@ class DogecoinWallet extends CoinServiceAPI { if (prevOut == out["n"]) { inputAmtSentFromWallet += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2157,7 +2161,7 @@ class DogecoinWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["addresses"][0]; final value = output["value"]; final _value = (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOutput += _value; @@ -2182,7 +2186,7 @@ class DogecoinWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["addresses"][0]; if (address != null) { final value = (Decimal.parse(output["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOut += value; @@ -2205,7 +2209,7 @@ class DogecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { totalIn += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2227,7 +2231,7 @@ class DogecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -2237,7 +2241,7 @@ class DogecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = outputAmtAddressedToWallet; final worthNow = ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -3050,7 +3054,8 @@ class DogecoinWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - final available = Format.decimalAmountToSatoshis(await availableBalance); + final available = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index 4bd863f2c..3e0cba75d 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -620,7 +620,7 @@ Future isolateCreateJoinSplitTransaction( "txid": txId, "txHex": txHex, "value": amount, - "fees": Format.satoshisToAmount(fee).toDouble(), + "fees": Format.satoshisToAmount(fee, coin: coin).toDouble(), "fee": fee, "vSize": extTx.virtualSize(), "jmintValue": changeToMint, @@ -629,11 +629,11 @@ Future isolateCreateJoinSplitTransaction( "height": locktime, "txType": "Sent", "confirmed_status": false, - "amount": Format.satoshisToAmount(amount).toDouble(), + "amount": Format.satoshisToAmount(amount, coin: coin).toDouble(), "recipientAmt": amount, "worthNow": Format.localizedStringAsFixed( value: ((Decimal.fromInt(amount) * price) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale), @@ -883,7 +883,7 @@ class FiroWallet extends CoinServiceAPI { Future get balanceMinusMaxFee async { final balances = await this.balances; final maxFee = await this.maxFee; - return balances[0] - Format.satoshisToAmount(maxFee); + return balances[0] - Format.satoshisToAmount(maxFee, coin: coin); } @override @@ -919,7 +919,7 @@ class FiroWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1089,8 +1089,8 @@ class FiroWallet extends CoinServiceAPI { // check for send all bool isSendAll = false; - final balance = - Format.decimalAmountToSatoshis(await availablePublicBalance()); + final balance = Format.decimalAmountToSatoshis( + await availablePublicBalance(), coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1176,7 +1176,7 @@ class FiroWallet extends CoinServiceAPI { // check for send all bool isSendAll = false; final balance = - Format.decimalAmountToSatoshis(await availablePrivateBalance()); + Format.decimalAmountToSatoshis(await availablePrivateBalance(), coin); if (satoshiAmount == balance) { // print("is send all"); isSendAll = true; @@ -1222,7 +1222,8 @@ class FiroWallet extends CoinServiceAPI { // temporarily update apdate available balance until a full refresh is done // TODO: something here causes an exception to be thrown giving user false info that the tx failed - Decimal sendTotal = Format.satoshisToAmount(txData["value"] as int); + Decimal sendTotal = + Format.satoshisToAmount(txData["value"] as int, coin: coin); sendTotal += Decimal.parse(txData["fees"].toString()); final bals = await balances; bals[0] -= sendTotal; @@ -1270,7 +1271,7 @@ class FiroWallet extends CoinServiceAPI { // temporarily update apdate available balance until a full refresh is done Decimal sendTotal = - Format.satoshisToAmount(txHexOrError["value"] as int); + Format.satoshisToAmount(txHexOrError["value"] as int, coin: coin); sendTotal += Decimal.parse(txHexOrError["fees"].toString()); final bals = await balances; bals[0] -= sendTotal; @@ -2333,8 +2334,9 @@ class FiroWallet extends CoinServiceAPI { Future _fetchMaxFee() async { final balance = await availableBalance; - int spendAmount = - (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt(); + int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin))) + .toBigInt() + .toInt(); int fee = await estimateJoinSplitFee(spendAmount); return fee; } @@ -2480,18 +2482,20 @@ class FiroWallet extends CoinServiceAPI { } final int utxosIntValue = utxos.satoshiBalance; - final Decimal utxosValue = Format.satoshisToAmount(utxosIntValue); + final Decimal utxosValue = + Format.satoshisToAmount(utxosIntValue, coin: coin); List balances = List.empty(growable: true); - Decimal lelantusBalance = Format.satoshisToAmount(intLelantusBalance); + Decimal lelantusBalance = + Format.satoshisToAmount(intLelantusBalance, coin: coin); balances.add(lelantusBalance); balances.add(lelantusBalance * price); Decimal _unconfirmedLelantusBalance = - Format.satoshisToAmount(unconfirmedLelantusBalance); + Format.satoshisToAmount(unconfirmedLelantusBalance, coin: coin); balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance); @@ -2503,7 +2507,7 @@ class FiroWallet extends CoinServiceAPI { if (availableSats < 0) { availableSats = 0; } - balances.add(Format.satoshisToAmount(availableSats)); + balances.add(Format.satoshisToAmount(availableSats, coin: coin)); Logging.instance.log("balances $balances", level: LogLevel.Info); await DB.instance.put( @@ -2601,7 +2605,8 @@ class FiroWallet extends CoinServiceAPI { final feesObject = await fees; - final Decimal fastFee = Format.satoshisToAmount(feesObject.fast); + final Decimal fastFee = + Format.satoshisToAmount(feesObject.fast, coin: coin); int firoFee = (dvsize * fastFee * Decimal.fromInt(100000)).toDouble().ceil(); // int firoFee = (vsize * feesObject.fast * (1 / 1000.0) * 100000000).ceil(); @@ -2789,15 +2794,15 @@ class FiroWallet extends CoinServiceAPI { "txid": txId, "txHex": txHex, "value": amount - fee, - "fees": Format.satoshisToAmount(fee).toDouble(), + "fees": Format.satoshisToAmount(fee, coin: coin).toDouble(), "publicCoin": "", "height": height, "txType": "Sent", "confirmed_status": false, - "amount": Format.satoshisToAmount(amount).toDouble(), + "amount": Format.satoshisToAmount(amount, coin: coin).toDouble(), "worthNow": Format.localizedStringAsFixed( value: ((Decimal.fromInt(amount) * price) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!), @@ -3040,9 +3045,9 @@ class FiroWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -3328,7 +3333,7 @@ class FiroWallet extends CoinServiceAPI { if (nFees != null) { nFeesUsed = true; fees = (Decimal.parse(nFees.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -3353,7 +3358,7 @@ class FiroWallet extends CoinServiceAPI { if (value != null) { if (changeAddresses.contains(address)) { inputAmtSentFromWallet -= (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } else { @@ -3363,7 +3368,7 @@ class FiroWallet extends CoinServiceAPI { } if (value != null) { outAmount += (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -3376,7 +3381,7 @@ class FiroWallet extends CoinServiceAPI { final nFees = input["nFees"]; if (nFees != null) { fees += (Decimal.parse(nFees.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -3391,7 +3396,7 @@ class FiroWallet extends CoinServiceAPI { if (allAddresses.contains(address)) { outputAmtAddressedToWallet += (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); outAddress = address; @@ -3413,7 +3418,7 @@ class FiroWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -3428,7 +3433,7 @@ class FiroWallet extends CoinServiceAPI { final worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -3589,7 +3594,7 @@ class FiroWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -3600,15 +3605,16 @@ class FiroWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -4571,8 +4577,9 @@ class FiroWallet extends CoinServiceAPI { ) async { var lelantusEntry = await _getLelantusEntry(); final balance = await availableBalance; - int spendAmount = - (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt(); + int spendAmount = (balance * Decimal.fromInt(Constants.satsPerCoin(coin))) + .toBigInt() + .toInt(); if (spendAmount == 0 || lelantusEntry.isEmpty) { return LelantusFeeData(0, 0, []).fee; } @@ -4633,7 +4640,7 @@ class FiroWallet extends CoinServiceAPI { Future estimateFeeForPublic(int satoshiAmount, int feeRate) async { final available = - Format.decimalAmountToSatoshis(await availablePublicBalance()); + Format.decimalAmountToSatoshis(await availablePublicBalance(), coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/litecoin/litecoin_wallet.dart b/lib/services/coins/litecoin/litecoin_wallet.dart index db7c9d1fa..9c4bb2305 100644 --- a/lib/services/coins/litecoin/litecoin_wallet.dart +++ b/lib/services/coins/litecoin/litecoin_wallet.dart @@ -200,19 +200,21 @@ class LitecoinWallet extends CoinServiceAPI { Future get availableBalance async { final data = await utxoData; return Format.satoshisToAmount( - data.satoshiBalance - data.satoshiBalanceUnconfirmed); + data.satoshiBalance - data.satoshiBalanceUnconfirmed, + coin: coin); } @override Future get pendingBalance async { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed); + return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin); } @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -222,13 +224,13 @@ class LitecoinWallet extends CoinServiceAPI { .get(boxName: walletId, key: 'totalBalance') as int?; if (totalBalance == null) { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } else { - return Format.satoshisToAmount(totalBalance); + return Format.satoshisToAmount(totalBalance, coin: coin); } } final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } @override @@ -266,7 +268,8 @@ class LitecoinWallet extends CoinServiceAPI { @override Future get maxFee async { final fee = (await fees).fast as String; - final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin); + final satsFee = + Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin)); return satsFee.floor().toBigInt().toInt(); } @@ -1095,7 +1098,8 @@ class LitecoinWallet extends CoinServiceAPI { // check for send all bool isSendAll = false; - final balance = Format.decimalAmountToSatoshis(await availableBalance); + final balance = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1299,7 +1303,7 @@ class LitecoinWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1499,9 +1503,9 @@ class LitecoinWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -1978,7 +1982,7 @@ class LitecoinWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -1988,15 +1992,16 @@ class LitecoinWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -2543,7 +2548,7 @@ class LitecoinWallet extends CoinServiceAPI { if (prevOut == out["n"]) { inputAmtSentFromWallet += (Decimal.parse(out["value"]!.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2557,7 +2562,7 @@ class LitecoinWallet extends CoinServiceAPI { output["scriptPubKey"]!["addresses"][0] as String; final value = output["value"]!; final _value = (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOutput += _value; @@ -2582,7 +2587,7 @@ class LitecoinWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["addresses"][0]; if (address != null) { final value = (Decimal.parse(output["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOut += value; @@ -2605,7 +2610,7 @@ class LitecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { totalIn += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2627,7 +2632,7 @@ class LitecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -2637,7 +2642,7 @@ class LitecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = outputAmtAddressedToWallet; final worthNow = ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -3769,7 +3774,8 @@ class LitecoinWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - final available = Format.decimalAmountToSatoshis(await availableBalance); + final available = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index f94f0cd2a..58bd36c72 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -44,6 +44,7 @@ import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -533,7 +534,8 @@ class MoneroWallet extends CoinServiceAPI { @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -542,16 +544,16 @@ class MoneroWallet extends CoinServiceAPI { @override Future exit() async { - await stopSyncPercentTimer(); _hasCalledExit = true; - isActive = false; - await walletBase?.save(prioritySave: true); - walletBase?.close(); + stopNetworkAlivePinging(); moneroAutosaveTimer?.cancel(); moneroAutosaveTimer = null; timer?.cancel(); timer = null; - stopNetworkAlivePinging(); + await stopSyncPercentTimer(); + await walletBase?.save(prioritySave: true); + walletBase?.close(); + isActive = false; } bool _hasCalledExit = false; @@ -562,13 +564,15 @@ class MoneroWallet extends CoinServiceAPI { Future? _currentReceivingAddress; Future _getFees() async { + // TODO: not use hard coded values here return FeeObject( - numberOfBlocksFast: 10, - numberOfBlocksAverage: 10, - numberOfBlocksSlow: 10, - fast: 4, - medium: 2, - slow: 0); + numberOfBlocksFast: 10, + numberOfBlocksAverage: 10, + numberOfBlocksSlow: 10, + fast: MoneroTransactionPriority.fast.raw!, + medium: MoneroTransactionPriority.regular.raw!, + slow: MoneroTransactionPriority.slow.raw!, + ); } @override @@ -868,8 +872,9 @@ class MoneroWallet extends CoinServiceAPI { Future get maxFee async { var bal = await availableBalance; var fee = walletBase!.calculateEstimatedFee( - monero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/ - 10000; + monero.getDefaultTransactionPriority(), + Format.decimalAmountToSatoshis(bal, coin), + ); return fee; } @@ -1372,7 +1377,6 @@ class MoneroWallet extends CoinServiceAPI { } @override - // TODO: implement availableBalance Future get availableBalance async { var bal = 0; for (var element in walletBase!.balance!.entries) { @@ -1421,13 +1425,13 @@ class MoneroWallet extends CoinServiceAPI { try { final feeRate = args?["feeRate"]; if (feeRate is FeeRateType) { - MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow; + MoneroTransactionPriority feePriority; switch (feeRate) { case FeeRateType.fast: - feePriority = MoneroTransactionPriority.fastest; + feePriority = MoneroTransactionPriority.fast; break; case FeeRateType.average: - feePriority = MoneroTransactionPriority.medium; + feePriority = MoneroTransactionPriority.regular; break; case FeeRateType.slow: feePriority = MoneroTransactionPriority.slow; @@ -1440,15 +1444,14 @@ class MoneroWallet extends CoinServiceAPI { bool isSendAll = false; final balance = await availableBalance; final satInDecimal = ((Decimal.fromInt(satoshiAmount) / - Decimal.fromInt(Constants.satsPerCoinMonero)) - .toDecimal() * - Decimal.fromInt(10000)); + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal()); if (satInDecimal == balance) { isSendAll = true; } Logging.instance .log("$toAddress $amount $args", level: LogLevel.Info); - String amountToSend = moneroAmountToString(amount: amount * 10000); + String amountToSend = moneroAmountToString(amount: amount); Logging.instance.log("$amount $amountToSend", level: LogLevel.Info); monero_output.Output output = monero_output.Output(walletBase!); @@ -1470,10 +1473,9 @@ class MoneroWallet extends CoinServiceAPI { PendingMoneroTransaction pendingMoneroTransaction = await (awaitPendingTransaction!) as PendingMoneroTransaction; - int realfee = (Decimal.parse(pendingMoneroTransaction.feeFormatted) * - 100000000.toDecimal()) - .toBigInt() - .toInt(); + + int realfee = Format.decimalAmountToSatoshis( + Decimal.parse(pendingMoneroTransaction.feeFormatted), coin); debugPrint("fee? $realfee"); Map txData = { "pendingMoneroTransaction": pendingMoneroTransaction, @@ -1506,12 +1508,13 @@ class MoneroWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - MoneroTransactionPriority? priority; - FeeRateType feeRateType = FeeRateType.slow; + MoneroTransactionPriority priority; + FeeRateType feeRateType; + switch (feeRate) { case 1: priority = MoneroTransactionPriority.regular; - feeRateType = FeeRateType.slow; + feeRateType = FeeRateType.average; break; case 2: priority = MoneroTransactionPriority.medium; @@ -1519,7 +1522,7 @@ class MoneroWallet extends CoinServiceAPI { break; case 3: priority = MoneroTransactionPriority.fast; - feeRateType = FeeRateType.average; + feeRateType = FeeRateType.fast; break; case 4: priority = MoneroTransactionPriority.fastest; @@ -1531,27 +1534,29 @@ class MoneroWallet extends CoinServiceAPI { feeRateType = FeeRateType.slow; break; } - var aprox; + // int? aprox; - await estimateFeeMutex.protect(() async { - { - try { - aprox = (await prepareSend( - // This address is only used for getting an approximate fee, never for sending - address: - "8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7", - satoshiAmount: satoshiAmount, - args: {"feeRate": feeRateType}))['fee']; - await Future.delayed(const Duration(milliseconds: 1000)); - } catch (e, s) { - Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error); - aprox = -9999999999999999; - } - } - }); + // corrupted size vs. prev_size occurs but not sure if related to fees or just generating monero transactions in general + + // await estimateFeeMutex.protect(() async { + // { + // try { + // aprox = (await prepareSend( + // // This address is only used for getting an approximate fee, never for sending + // address: + // "8347huhmj6Ggzr1BpZPJAD5oa96ob5Fe8GtQdGZDYVVYVsCgtUNH3pEEzExDuaAVZdC16D4FkAb24J6wUfsKkcZtC8EPXB7", + // satoshiAmount: satoshiAmount, + // args: {"feeRate": feeRateType}))['fee'] as int?; + // await Future.delayed(const Duration(milliseconds: 1000)); + // } catch (e, s) { + // Logging.instance.log("$feeRateType $e $s", level: LogLevel.Error); + final aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount); + // } + // } + // }); print("this is the aprox fee $aprox for $satoshiAmount"); - final fee = (aprox as int); + final fee = aprox; return fee; } diff --git a/lib/services/coins/namecoin/namecoin_wallet.dart b/lib/services/coins/namecoin/namecoin_wallet.dart index c8c84fb27..142bfb379 100644 --- a/lib/services/coins/namecoin/namecoin_wallet.dart +++ b/lib/services/coins/namecoin/namecoin_wallet.dart @@ -196,19 +196,21 @@ class NamecoinWallet extends CoinServiceAPI { Future get availableBalance async { final data = await utxoData; return Format.satoshisToAmount( - data.satoshiBalance - data.satoshiBalanceUnconfirmed); + data.satoshiBalance - data.satoshiBalanceUnconfirmed, + coin: coin); } @override Future get pendingBalance async { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed); + return Format.satoshisToAmount(data.satoshiBalanceUnconfirmed, coin: coin); } @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) + (Decimal.fromInt((await maxFee)) / + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(); @override @@ -218,13 +220,13 @@ class NamecoinWallet extends CoinServiceAPI { .get(boxName: walletId, key: 'totalBalance') as int?; if (totalBalance == null) { final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } else { - return Format.satoshisToAmount(totalBalance); + return Format.satoshisToAmount(totalBalance, coin: coin); } } final data = await utxoData; - return Format.satoshisToAmount(data.satoshiBalance); + return Format.satoshisToAmount(data.satoshiBalance, coin: coin); } @override @@ -262,7 +264,8 @@ class NamecoinWallet extends CoinServiceAPI { @override Future get maxFee async { final fee = (await fees).fast as String; - final satsFee = Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin); + final satsFee = + Decimal.parse(fee) * Decimal.fromInt(Constants.satsPerCoin(coin)); return satsFee.floor().toBigInt().toInt(); } @@ -1086,7 +1089,8 @@ class NamecoinWallet extends CoinServiceAPI { // check for send all bool isSendAll = false; - final balance = Format.decimalAmountToSatoshis(await availableBalance); + final balance = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (satoshiAmount == balance) { isSendAll = true; } @@ -1290,7 +1294,7 @@ class NamecoinWallet extends CoinServiceAPI { final String worthNow = Format.localizedStringAsFixed( value: ((currentPrice * Decimal.fromInt(txData["recipientAmt"] as int)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2), decimalPlaces: 2, locale: locale!); @@ -1490,9 +1494,9 @@ class NamecoinWallet extends CoinServiceAPI { numberOfBlocksFast: f, numberOfBlocksAverage: m, numberOfBlocksSlow: s, - fast: Format.decimalAmountToSatoshis(fast), - medium: Format.decimalAmountToSatoshis(medium), - slow: Format.decimalAmountToSatoshis(slow), + fast: Format.decimalAmountToSatoshis(fast, coin), + medium: Format.decimalAmountToSatoshis(medium, coin), + slow: Format.decimalAmountToSatoshis(slow, coin), ); Logging.instance.log("fetched fees: $feeObject", level: LogLevel.Info); @@ -1965,7 +1969,7 @@ class NamecoinWallet extends CoinServiceAPI { utxo["status"]["block_time"] = txn["blocktime"]; final fiatValue = ((Decimal.fromInt(value) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); utxo["rawWorth"] = fiatValue; utxo["fiatWorth"] = fiatValue.toString(); @@ -1975,15 +1979,16 @@ class NamecoinWallet extends CoinServiceAPI { Decimal currencyBalanceRaw = ((Decimal.fromInt(satoshiBalance) * currentPrice) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2); final Map result = { "total_user_currency": currencyBalanceRaw.toString(), "total_sats": satoshiBalance, "total_btc": (Decimal.fromInt(satoshiBalance) / - Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces) + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)) .toString(), "outputArray": outputArray, "unconfirmed": satoshiBalancePending, @@ -2540,7 +2545,7 @@ class NamecoinWallet extends CoinServiceAPI { if (prevOut == out["n"]) { inputAmtSentFromWallet += (Decimal.parse(out["value"]!.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2554,7 +2559,7 @@ class NamecoinWallet extends CoinServiceAPI { final address = output["scriptPubKey"]["address"]; final value = output["value"]; final _value = (Decimal.parse(value.toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOutput += _value; @@ -2582,7 +2587,7 @@ class NamecoinWallet extends CoinServiceAPI { } if (address != null) { final value = (Decimal.parse(output["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); totalOut += value; @@ -2605,7 +2610,7 @@ class NamecoinWallet extends CoinServiceAPI { for (final out in tx["vout"] as List) { if (prevOut == out["n"]) { totalIn += (Decimal.parse(out["value"].toString()) * - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toBigInt() .toInt(); } @@ -2627,7 +2632,7 @@ class NamecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = inputAmtSentFromWallet; final String worthNow = ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -2637,7 +2642,7 @@ class NamecoinWallet extends CoinServiceAPI { midSortedTx["amount"] = outputAmtAddressedToWallet; final worthNow = ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) / - Decimal.fromInt(Constants.satsPerCoin)) + Decimal.fromInt(Constants.satsPerCoin(coin))) .toDecimal(scaleOnInfinitePrecision: 2) .toStringAsFixed(2); midSortedTx["worthNow"] = worthNow; @@ -3772,7 +3777,8 @@ class NamecoinWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - final available = Format.decimalAmountToSatoshis(await availableBalance); + final available = + Format.decimalAmountToSatoshis(await availableBalance, coin); if (available == satoshiAmount) { return satoshiAmount - sweepAllEstimate(feeRate); diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index e6a531b78..686dcd08c 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -45,6 +45,7 @@ import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -534,8 +535,7 @@ class WowneroWallet extends CoinServiceAPI { @override Future get balanceMinusMaxFee async => (await availableBalance) - - (Decimal.fromInt((await maxFee)) / Decimal.fromInt(Constants.satsPerCoin)) - .toDecimal(); + Format.satoshisToAmount(await maxFee, coin: Coin.wownero); @override Future get currentReceivingAddress => @@ -563,13 +563,15 @@ class WowneroWallet extends CoinServiceAPI { Future? _currentReceivingAddress; Future _getFees() async { + // TODO: not use hard coded values here return FeeObject( - numberOfBlocksFast: 10, - numberOfBlocksAverage: 10, - numberOfBlocksSlow: 10, - fast: 4, - medium: 2, - slow: 0); + numberOfBlocksFast: 10, + numberOfBlocksAverage: 10, + numberOfBlocksSlow: 10, + fast: MoneroTransactionPriority.fast.raw!, + medium: MoneroTransactionPriority.regular.raw!, + slow: MoneroTransactionPriority.slow.raw!, + ); } @override @@ -873,8 +875,9 @@ class WowneroWallet extends CoinServiceAPI { Future get maxFee async { var bal = await availableBalance; var fee = walletBase!.calculateEstimatedFee( - wownero.getDefaultTransactionPriority(), bal.toBigInt().toInt()) ~/ - 10000; + wownero.getDefaultTransactionPriority(), + Format.decimalAmountToSatoshis(bal, coin), + ); return fee; } @@ -1446,13 +1449,13 @@ class WowneroWallet extends CoinServiceAPI { try { final feeRate = args?["feeRate"]; if (feeRate is FeeRateType) { - MoneroTransactionPriority feePriority = MoneroTransactionPriority.slow; + MoneroTransactionPriority feePriority; switch (feeRate) { case FeeRateType.fast: - feePriority = MoneroTransactionPriority.fastest; + feePriority = MoneroTransactionPriority.fast; break; case FeeRateType.average: - feePriority = MoneroTransactionPriority.medium; + feePriority = MoneroTransactionPriority.regular; break; case FeeRateType.slow: feePriority = MoneroTransactionPriority.slow; @@ -1465,15 +1468,14 @@ class WowneroWallet extends CoinServiceAPI { bool isSendAll = false; final balance = await availableBalance; final satInDecimal = ((Decimal.fromInt(satoshiAmount) / - Decimal.fromInt(Constants.satsPerCoinWownero)) - .toDecimal() * - Decimal.fromInt(1000)); + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal()); if (satInDecimal == balance) { isSendAll = true; } Logging.instance .log("$toAddress $amount $args", level: LogLevel.Info); - String amountToSend = wowneroAmountToString(amount: amount * 1000); + String amountToSend = wowneroAmountToString(amount: amount); Logging.instance.log("$amount $amountToSend", level: LogLevel.Info); wownero_output.Output output = wownero_output.Output(walletBase!); @@ -1495,10 +1497,8 @@ class WowneroWallet extends CoinServiceAPI { PendingWowneroTransaction pendingWowneroTransaction = await (awaitPendingTransaction!) as PendingWowneroTransaction; - int realfee = (Decimal.parse(pendingWowneroTransaction.feeFormatted) * - 100000000.toDecimal()) - .toBigInt() - .toInt(); + int realfee = Format.decimalAmountToSatoshis( + Decimal.parse(pendingWowneroTransaction.feeFormatted), coin); debugPrint("fee? $realfee"); Map txData = { "pendingWowneroTransaction": pendingWowneroTransaction, @@ -1531,12 +1531,12 @@ class WowneroWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { - MoneroTransactionPriority? priority; + MoneroTransactionPriority priority; FeeRateType feeRateType = FeeRateType.slow; switch (feeRate) { case 1: priority = MoneroTransactionPriority.regular; - feeRateType = FeeRateType.slow; + feeRateType = FeeRateType.average; break; case 2: priority = MoneroTransactionPriority.medium; @@ -1544,7 +1544,7 @@ class WowneroWallet extends CoinServiceAPI { break; case 3: priority = MoneroTransactionPriority.fast; - feeRateType = FeeRateType.average; + feeRateType = FeeRateType.fast; break; case 4: priority = MoneroTransactionPriority.fastest; @@ -1568,7 +1568,7 @@ class WowneroWallet extends CoinServiceAPI { args: {"feeRate": feeRateType}))['fee']; await Future.delayed(const Duration(milliseconds: 500)); } catch (e, s) { - aprox = -9999999999999999; + aprox = walletBase!.calculateEstimatedFee(priority, satoshiAmount); } } }); diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart index 0a062de67..3263d526e 100644 --- a/lib/utilities/constants.dart +++ b/lib/utilities/constants.dart @@ -23,12 +23,12 @@ abstract class Constants { static bool enableExchange = Util.isDesktop || !Platform.isIOS; //TODO: correct for monero? - static const int satsPerCoinMonero = 1000000000000; - static const int satsPerCoinWownero = 100000000000; - static const int satsPerCoin = 100000000; - static const int decimalPlaces = 8; - static const int decimalPlacesWownero = 11; - static const int decimalPlacesMonero = 12; + static const int _satsPerCoinMonero = 1000000000000; + static const int _satsPerCoinWownero = 100000000000; + static const int _satsPerCoin = 100000000; + static const int _decimalPlaces = 8; + static const int _decimalPlacesWownero = 11; + static const int _decimalPlacesMonero = 12; static const int notificationsMax = 0xFFFFFFFF; static const Duration networkAliveTimerDuration = Duration(seconds: 10); @@ -40,6 +40,30 @@ abstract class Constants { static const int currentHiveDbVersion = 3; + static int satsPerCoin(Coin coin) { + switch (coin) { + case Coin.bitcoin: + case Coin.litecoin: + case Coin.litecoinTestNet: + case Coin.bitcoincash: + case Coin.bitcoincashTestnet: + case Coin.dogecoin: + case Coin.firo: + case Coin.bitcoinTestNet: + case Coin.dogecoinTestNet: + case Coin.firoTestNet: + case Coin.epicCash: + case Coin.namecoin: + return _satsPerCoin; + + case Coin.wownero: + return _satsPerCoinWownero; + + case Coin.monero: + return _satsPerCoinMonero; + } + } + static int decimalPlacesForCoin(Coin coin) { switch (coin) { case Coin.bitcoin: @@ -54,13 +78,13 @@ abstract class Constants { case Coin.firoTestNet: case Coin.epicCash: case Coin.namecoin: - return decimalPlaces; + return _decimalPlaces; case Coin.wownero: - return decimalPlacesWownero; + return _decimalPlacesWownero; case Coin.monero: - return decimalPlacesMonero; + return _decimalPlacesMonero; } } diff --git a/lib/utilities/format.dart b/lib/utilities/format.dart index 775780833..136ec5b95 100644 --- a/lib/utilities/format.dart +++ b/lib/utilities/format.dart @@ -8,46 +8,28 @@ import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; abstract class Format { - static Decimal satoshisToAmount(int sats, {Coin? coin}) { - late final int satsPerCoin; - - switch (coin) { - case Coin.wownero: - satsPerCoin = Constants.satsPerCoinWownero; - break; - case Coin.monero: - satsPerCoin = Constants.satsPerCoinMonero; - break; - case Coin.bitcoin: - case Coin.bitcoincash: - case Coin.dogecoin: - case Coin.epicCash: - case Coin.firo: - case Coin.litecoin: - case Coin.namecoin: - case Coin.bitcoinTestNet: - case Coin.litecoinTestNet: - case Coin.bitcoincashTestnet: - case Coin.dogecoinTestNet: - case Coin.firoTestNet: - default: - satsPerCoin = Constants.satsPerCoin; - } - - return (Decimal.fromInt(sats) / Decimal.fromInt(satsPerCoin)) - .toDecimal(scaleOnInfinitePrecision: Constants.decimalPlaces); + static Decimal satoshisToAmount(int sats, {required Coin coin}) { + return (Decimal.fromInt(sats) / + Decimal.fromInt(Constants.satsPerCoin(coin))) + .toDecimal( + scaleOnInfinitePrecision: Constants.decimalPlacesForCoin(coin)); } /// - static String satoshiAmountToPrettyString(int sats, String locale) { - final amount = satoshisToAmount(sats); + static String satoshiAmountToPrettyString( + int sats, String locale, Coin coin) { + final amount = satoshisToAmount(sats, coin: coin); return localizedStringAsFixed( - value: amount, locale: locale, decimalPlaces: Constants.decimalPlaces); + value: amount, + locale: locale, + decimalPlaces: Constants.decimalPlacesForCoin(coin), + ); } - static int decimalAmountToSatoshis(Decimal amount) { - final value = - (Decimal.fromInt(Constants.satsPerCoin) * amount).floor().toBigInt(); + static int decimalAmountToSatoshis(Decimal amount, Coin coin) { + final value = (Decimal.fromInt(Constants.satsPerCoin(coin)) * amount) + .floor() + .toBigInt(); return value.toInt(); } diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart index 15dcf2b4d..4389573c3 100644 --- a/lib/widgets/transaction_card.dart +++ b/lib/widgets/transaction_card.dart @@ -9,7 +9,6 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_deta import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/enums/flush_bar_type.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; @@ -198,13 +197,9 @@ class _TransactionCardState extends ConsumerState { fit: BoxFit.scaleDown, child: Builder( builder: (_) { - final amount = coin == Coin.monero - ? (_transaction.amount ~/ 10000) - : coin == Coin.wownero - ? (_transaction.amount ~/ 1000) - : _transaction.amount; + final amount = _transaction.amount; return Text( - "$prefix${Format.satoshiAmountToPrettyString(amount, locale)} ${coin.ticker}", + "$prefix${Format.satoshiAmountToPrettyString(amount, locale, coin)} ${coin.ticker}", style: STextStyles.itemSubtitle12_600(context), ); @@ -242,17 +237,12 @@ class _TransactionCardState extends ConsumerState { fit: BoxFit.scaleDown, child: Builder( builder: (_) { - // TODO: modify Format. to take optional Coin parameter so this type oif check isn't done in ui int value = _transaction.amount; - if (coin == Coin.monero) { - value = (value ~/ 10000); - } else if (coin == Coin.wownero) { - value = (value ~/ 1000); - } return Text( "$prefix${Format.localizedStringAsFixed( - value: Format.satoshisToAmount(value) * + value: Format.satoshisToAmount(value, + coin: coin) * price, locale: locale, decimalPlaces: 2, From ffe9a83abf170b7082a24f030b5219daefe9d203 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 12:38:36 -0600 Subject: [PATCH 08/11] Format tests updated --- test/formet_test.dart | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/test/formet_test.dart b/test/formet_test.dart index 4f7136cd4..e27293114 100644 --- a/test/formet_test.dart +++ b/test/formet_test.dart @@ -1,54 +1,64 @@ import 'package:decimal/decimal.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/format.dart'; void main() { group("satoshisToAmount", () { test("12345", () { - expect(Format.satoshisToAmount(12345), Decimal.parse("0.00012345")); + expect(Format.satoshisToAmount(12345, coin: Coin.bitcoin), + Decimal.parse("0.00012345")); }); test("100012345", () { - expect(Format.satoshisToAmount(100012345), Decimal.parse("1.00012345")); + expect(Format.satoshisToAmount(100012345, coin: Coin.bitcoin), + Decimal.parse("1.00012345")); }); test("0", () { - expect(Format.satoshisToAmount(0), Decimal.zero); + expect(Format.satoshisToAmount(0, coin: Coin.bitcoin), Decimal.zero); }); test("1000000000", () { - expect(Format.satoshisToAmount(1000000000), Decimal.parse("10")); + expect(Format.satoshisToAmount(1000000000, coin: Coin.bitcoin), + Decimal.parse("10")); }); }); group("satoshiAmountToPrettyString", () { const locale = "en_US"; test("12345", () { - expect(Format.satoshiAmountToPrettyString(12345, locale), "0.00012345"); + expect(Format.satoshiAmountToPrettyString(12345, locale, Coin.bitcoin), + "0.00012345"); }); test("100012345", () { expect( - Format.satoshiAmountToPrettyString(100012345, locale), "1.00012345"); + Format.satoshiAmountToPrettyString(100012345, locale, Coin.bitcoin), + "1.00012345"); }); test("123450000", () { expect( - Format.satoshiAmountToPrettyString(123450000, locale), "1.23450000"); + Format.satoshiAmountToPrettyString(123450000, locale, Coin.bitcoin), + "1.23450000"); }); test("1230045000", () { - expect(Format.satoshiAmountToPrettyString(1230045000, locale), + expect( + Format.satoshiAmountToPrettyString(1230045000, locale, Coin.bitcoin), "12.30045000"); }); test("1000000000", () { - expect(Format.satoshiAmountToPrettyString(1000000000, locale), + expect( + Format.satoshiAmountToPrettyString(1000000000, locale, Coin.bitcoin), "10.00000000"); }); test("0", () { - expect(Format.satoshiAmountToPrettyString(0, locale), "0.00000000"); + expect(Format.satoshiAmountToPrettyString(0, locale, Coin.bitcoin), + "0.00000000"); }); }); From 85b9fdc2f3c07f353166deb2a087bbf52ca50ef4 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 12:42:08 -0600 Subject: [PATCH 09/11] random hardcoded values :/ --- lib/services/coins/monero/monero_wallet.dart | 6 +++--- lib/services/coins/wownero/wownero_wallet.dart | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/services/coins/monero/monero_wallet.dart b/lib/services/coins/monero/monero_wallet.dart index 58bd36c72..6f1e49ee5 100644 --- a/lib/services/coins/monero/monero_wallet.dart +++ b/lib/services/coins/monero/monero_wallet.dart @@ -564,11 +564,11 @@ class MoneroWallet extends CoinServiceAPI { Future? _currentReceivingAddress; Future _getFees() async { - // TODO: not use hard coded values here + // TODO: not use random hard coded values here return FeeObject( numberOfBlocksFast: 10, - numberOfBlocksAverage: 10, - numberOfBlocksSlow: 10, + numberOfBlocksAverage: 15, + numberOfBlocksSlow: 20, fast: MoneroTransactionPriority.fast.raw!, medium: MoneroTransactionPriority.regular.raw!, slow: MoneroTransactionPriority.slow.raw!, diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index 686dcd08c..72580ea4a 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -563,11 +563,11 @@ class WowneroWallet extends CoinServiceAPI { Future? _currentReceivingAddress; Future _getFees() async { - // TODO: not use hard coded values here + // TODO: not use random hard coded values here return FeeObject( numberOfBlocksFast: 10, - numberOfBlocksAverage: 10, - numberOfBlocksSlow: 10, + numberOfBlocksAverage: 15, + numberOfBlocksSlow: 20, fast: MoneroTransactionPriority.fast.raw!, medium: MoneroTransactionPriority.regular.raw!, slow: MoneroTransactionPriority.slow.raw!, From d14593407df61ebf656028bc88985fa0e27172ad Mon Sep 17 00:00:00 2001 From: ryleedavis Date: Wed, 23 Nov 2022 17:48:58 -0700 Subject: [PATCH 10/11] v1.5.19 build 91 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index f79879f61..7ca368d29 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.5.18+90 +version: 1.5.19+91 environment: sdk: ">=2.17.0 <3.0.0" From 08c6fb72ac8fe2cd4eed91c403d83be65459e874 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 23 Nov 2022 14:55:04 -0600 Subject: [PATCH 11/11] mobile confirm send button height fix --- lib/pages/send_view/confirm_transaction_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 1ddeb3c9f..fd5341dd9 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -780,7 +780,7 @@ class _ConfirmTransactionViewState : const EdgeInsets.all(0), child: PrimaryButton( label: "Send", - buttonHeight: ButtonHeight.l, + buttonHeight: isDesktop ? ButtonHeight.l : null, onPressed: () async { final dynamic unlocked;