From 764c66ee084e7c5f427bfd797aac4b604bd480e1 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 12 Oct 2022 18:09:17 -0600 Subject: [PATCH 1/4] fix ui bug where chosen fee field doesnt show the updated user fee --- lib/pages/send_view/send_view.dart | 6 ++ .../transaction_fee_selection_sheet.dart | 56 +++++++++++++++++++ .../coins/wownero/wownero_wallet.dart | 2 +- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index 25264e19c..17dd9219d 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -1319,6 +1319,12 @@ class _SendViewState extends ConsumerState { cryptoAmountController .text) ?? Decimal.zero, + updateChosen: (String fee) { + setState(() { + _calculateFeesFuture = + Future(() => fee); + }); + }, ), ); }, 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 05644cf70..982086d3c 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 @@ -32,10 +32,12 @@ class TransactionFeeSelectionSheet extends ConsumerStatefulWidget { Key? key, required this.walletId, required this.amount, + required this.updateChosen, }) : super(key: key); final String walletId; final Decimal amount; + final Function updateChosen; @override ConsumerState createState() => @@ -223,6 +225,10 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.fast; } + String? fee = getAmount(FeeRateType.fast); + if (fee != null) { + widget.updateChosen(fee); + } Navigator.of(context).pop(); }, child: Container( @@ -352,6 +358,10 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.average; } + String? fee = getAmount(FeeRateType.average); + if (fee != null) { + widget.updateChosen(fee); + } Navigator.of(context).pop(); }, child: Container( @@ -479,6 +489,11 @@ class _TransactionFeeSelectionSheetState ref.read(feeRateTypeStateProvider.state).state = FeeRateType.slow; } + String? fee = getAmount(FeeRateType.slow); + print("fee $fee"); + if (fee != null) { + widget.updateChosen(fee); + } Navigator.of(context).pop(); }, child: Container( @@ -608,4 +623,45 @@ class _TransactionFeeSelectionSheetState ), ); } + + String? getAmount(FeeRateType feeRateType) { + try { + print(feeRateType); + var amount = Format.decimalAmountToSatoshis(this.amount); + print(amount); + print(ref.read(feeSheetSessionCacheProvider).fast); + print(ref.read(feeSheetSessionCacheProvider).average); + print(ref.read(feeSheetSessionCacheProvider).slow); + switch (feeRateType) { + case FeeRateType.fast: + if (ref.read(feeSheetSessionCacheProvider).fast[amount] != null) { + return (ref.read(feeSheetSessionCacheProvider).fast[amount] + as Decimal) + .toString(); + } + return null; + + case FeeRateType.average: + if (ref.read(feeSheetSessionCacheProvider).average[amount] != null) { + return (ref.read(feeSheetSessionCacheProvider).average[amount] + as Decimal) + .toString(); + } + return null; + + case FeeRateType.slow: + print(ref.read(feeSheetSessionCacheProvider).slow); + print(ref.read(feeSheetSessionCacheProvider).slow[amount]); + if (ref.read(feeSheetSessionCacheProvider).slow[amount] != null) { + return (ref.read(feeSheetSessionCacheProvider).slow[amount] + as Decimal) + .toString(); + } + return null; + } + } catch (e, s) { + print("$e $s"); + return null; + } + } } diff --git a/lib/services/coins/wownero/wownero_wallet.dart b/lib/services/coins/wownero/wownero_wallet.dart index afdc49117..d3aba5bbb 100644 --- a/lib/services/coins/wownero/wownero_wallet.dart +++ b/lib/services/coins/wownero/wownero_wallet.dart @@ -1558,7 +1558,7 @@ class WowneroWallet extends CoinServiceAPI { "WW3iVcnoAY6K9zNdU4qmdvZELefx6xZz4PMpTwUifRkvMQckyadhSPYMVPJhBdYE8P9c27fg9RPmVaWNFx1cDaj61HnetqBiy", satoshiAmount: satoshiAmount, args: {"feeRate": feeRateType}))['fee']; - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 500)); } catch (e, s) { aprox = -9999999999999999; } From 3c29b9acdf752aa3f4d7b03c5090d794ab2d7003 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 13 Oct 2022 13:01:49 -0600 Subject: [PATCH 2/4] temp fix for firo infinite fee estimate --- lib/services/coins/firo/firo_wallet.dart | 80 ++++++++++++++++-------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index aafa5e6f2..3a925f015 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -4493,6 +4493,7 @@ class FiroWallet extends CoinServiceAPI { } } + // TODO: investigate the bug here where chosen is null, conditions, given one mint spendVal += chosen!.amount; coinsToSpend.insert(coinsToSpend.length, chosen); } @@ -4514,36 +4515,61 @@ class FiroWallet extends CoinServiceAPI { Future estimateJoinSplitFee( int spendAmount, ) async { - int fee; - int size; - - for (fee = 0;;) { - int currentRequired = spendAmount; - - var map = await getCoinsToJoinSplit(currentRequired); - if (map is bool && !map) { - return 0; - } - - List coinsToBeSpent = - map['coinsToSpend'] as List; - - // 1054 is constant part, mainly Schnorr and Range proofs, 2560 is for each sigma/aux data - // 179 other parts of tx, assuming 1 utxo and 1 jmint - size = 1054 + 2560 * coinsToBeSpent.length + 180; - // uint64_t feeNeeded = GetMinimumFee(size, DEFAULT_TX_CONFIRM_TARGET); - int feeNeeded = - size; //TODO(Levon) temporary, use real estimation methods here - - if (fee >= feeNeeded) { - break; - } - - fee = feeNeeded; + var lelantusEntry = await _getLelantusEntry(); + final balance = await availableBalance; + int spendAmount = + (balance * Decimal.fromInt(Constants.satsPerCoin)).toBigInt().toInt(); + if (spendAmount == 0 || lelantusEntry.isEmpty) { + return LelantusFeeData(0, 0, []).fee; } + ReceivePort receivePort = await getIsolate({ + "function": "estimateJoinSplit", + "spendAmount": spendAmount, + "subtractFeeFromAmount": true, + "lelantusEntries": lelantusEntry, + "coin": coin, + }); - return fee; + final message = await receivePort.first; + if (message is String) { + Logging.instance.log("this is a string", level: LogLevel.Error); + stop(receivePort); + throw Exception("_fetchMaxFee isolate failed"); + } + stop(receivePort); + Logging.instance.log('Closing estimateJoinSplit!', level: LogLevel.Info); + return (message as LelantusFeeData).fee; } + // int fee; + // int size; + // + // for (fee = 0;;) { + // int currentRequired = spendAmount; + // + // TODO: investigate the bug here + // var map = await getCoinsToJoinSplit(currentRequired); + // if (map is bool && !map) { + // return 0; + // } + // + // List coinsToBeSpent = + // map['coinsToSpend'] as List; + // + // // 1054 is constant part, mainly Schnorr and Range proofs, 2560 is for each sigma/aux data + // // 179 other parts of tx, assuming 1 utxo and 1 jmint + // size = 1054 + 2560 * coinsToBeSpent.length + 180; + // // uint64_t feeNeeded = GetMinimumFee(size, DEFAULT_TX_CONFIRM_TARGET); + // int feeNeeded = + // size; //TODO(Levon) temporary, use real estimation methods here + // + // if (fee >= feeNeeded) { + // break; + // } + // + // fee = feeNeeded; + // } + // + // return fee; @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { From a30ee6f32980994e3b7384f7d59cb095d97dae09 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 13 Oct 2022 13:31:24 -0600 Subject: [PATCH 3/4] increase firo gap check to 50 from 20 --- .../restore_wallet_view.dart | 2 +- .../helpers/restore_create_backup.dart | 2 +- .../sub_widgets/restoring_wallet_card.dart | 19 ++++++++++++++----- .../wallet_network_settings_view.dart | 10 +++++++++- .../services/coins/firo/firo_wallet_test.dart | 4 ++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart index 68f116a95..def0724b5 100644 --- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart +++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart @@ -275,7 +275,7 @@ class _RestoreWalletViewState extends ConsumerState { // without using them await manager.recoverFromMnemonic( mnemonic: mnemonic, - maxUnusedAddressGap: 20, + maxUnusedAddressGap: widget.coin == Coin.firo ? 50 : 20, maxNumberOfIndexesToCheck: 1000, height: height, ); diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart index bf964fec4..9c75f36e6 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart @@ -402,7 +402,7 @@ abstract class SWB { // without using them await manager.recoverFromMnemonic( mnemonic: mnemonic, - maxUnusedAddressGap: 20, + maxUnusedAddressGap: manager.coin == Coin.firo ? 50 : 20, maxNumberOfIndexesToCheck: 1000, height: restoreHeight, ); diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart index 8f9890a6a..55f0588d2 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart @@ -35,7 +35,8 @@ class _RestoringWalletCardState extends ConsumerState { case StackRestoringStatus.waiting: return SvgPicture.asset( Assets.svg.loader, - color: Theme.of(context).extension()!.buttonBackSecondary, + color: + Theme.of(context).extension()!.buttonBackSecondary, ); case StackRestoringStatus.restoring: return const LoadingIndicator(); @@ -95,7 +96,10 @@ class _RestoringWalletCardState extends ConsumerState { try { final mnemonicList = await manager.mnemonic; - const maxUnusedAddressGap = 20; + int maxUnusedAddressGap = 20; + if (coin == Coin.firo) { + maxUnusedAddressGap = 50; + } const maxNumberOfIndexesToCheck = 1000; if (mnemonicList.isEmpty) { @@ -155,14 +159,17 @@ class _RestoringWalletCardState extends ConsumerState { ? Container( height: 20, decoration: BoxDecoration( - color: Theme.of(context).extension()!.buttonBackSecondary, + color: Theme.of(context) + .extension()! + .buttonBackSecondary, borderRadius: BorderRadius.circular( 1000, ), ), child: RawMaterialButton( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - splashColor: Theme.of(context).extension()!.highlight, + splashColor: + Theme.of(context).extension()!.highlight, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 1000, @@ -187,7 +194,9 @@ class _RestoringWalletCardState extends ConsumerState { child: Text( "Show recovery phrase", style: STextStyles.infoSmall(context).copyWith( - color: Theme.of(context).extension()!.accentColorDark), + color: Theme.of(context) + .extension()! + .accentColorDark), ), ), ), diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart index c4045dc9b..5b1c57214 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart @@ -77,7 +77,8 @@ class _WalletNetworkSettingsViewState Future _attemptRescan() async { if (!Platform.isLinux) Wakelock.enable(); - const int maxUnusedAddressGap = 20; + int maxUnusedAddressGap = 20; + const int maxNumberOfIndexesToCheck = 1000; showDialog( @@ -88,6 +89,13 @@ class _WalletNetworkSettingsViewState ); try { + if (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .coin == + Coin.firo) { + maxUnusedAddressGap = 50; + } await ref .read(walletsChangeNotifierProvider) .getManager(widget.walletId) diff --git a/test/services/coins/firo/firo_wallet_test.dart b/test/services/coins/firo/firo_wallet_test.dart index b309044b8..22a505adf 100644 --- a/test/services/coins/firo/firo_wallet_test.dart +++ b/test/services/coins/firo/firo_wallet_test.dart @@ -3283,9 +3283,9 @@ void main() { "a5V5r6We6mNZzWJwGwEeRML3mEYLjvK39w", ]); - expect(await firo.maxFee, 1234); // ??? + expect(await firo.maxFee, 0); // ??? - expect(await firo.balanceMinusMaxFee, Decimal.parse("-0.00001234")); + expect(await firo.balanceMinusMaxFee, Decimal.parse("0")); }); test("wallet balance minus maxfee - wallet balance is not zero", () async { From 3bd0fca7378b71c13b0441626f16e32724f664de Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 13 Oct 2022 16:19:25 -0600 Subject: [PATCH 4/4] fix stack backup saving issues. android 10 still not working --- .../stack_backup_views/helpers/stack_file_system.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart index 3196938da..e57c5493f 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/stack_file_system.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:permission_handler/permission_handler.dart'; class StackFileSystem { Directory? rootPath; @@ -14,6 +15,9 @@ class StackFileSystem { final bool isDesktop = !(Platform.isAndroid || Platform.isIOS); Future prepareStorage() async { + if (Platform.isAndroid) { + await Permission.storage.request(); + } rootPath = (await getApplicationDocumentsDirectory()); debugPrint(rootPath!.absolute.toString()); if (Platform.isAndroid) { @@ -22,13 +26,13 @@ class StackFileSystem { debugPrint(rootPath!.absolute.toString()); Directory sampleFolder = - Directory('${rootPath!.path}/Documents/Stack_backups'); + Directory('${rootPath!.path}Documents/Stack_backups'); if (Platform.isIOS) { sampleFolder = Directory(rootPath!.path); } try { if (!sampleFolder.existsSync()) { - sampleFolder.createSync(); + sampleFolder.createSync(recursive: true); } } catch (e, s) { debugPrint("$e $s"); @@ -65,8 +69,7 @@ class StackFileSystem { result = await FilePicker.platform.pickFiles( dialogTitle: "Load backup file", initialDirectory: startPath!.path, - type: FileType.custom, - allowedExtensions: ['bin'], + type: FileType.any, allowCompression: false, lockParentWindow: true, );