dynamic max fee rate value (#1395)

This commit is contained in:
Serhii 2024-04-25 19:28:18 +03:00 committed by GitHub
parent 190c8e06b9
commit 9ff6da3d5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 54 additions and 9 deletions

View file

@ -291,4 +291,10 @@ class CWBitcoin extends Bitcoin {
outputsCount,
);
}
@override
int getMaxCustomFeeRate(Object wallet) {
final bitcoinWallet = wallet as ElectrumWallet;
return (bitcoinWallet.feeRate(BitcoinTransactionPriority.fast) * 1.1).round();
}
}

View file

@ -675,6 +675,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
final selectedItem = items.indexOf(sendViewModel.transactionPriority);
final customItemIndex = sendViewModel.getCustomPriorityIndex(items);
final isBitcoinWallet = sendViewModel.walletType == WalletType.bitcoin;
final maxCustomFeeRate = sendViewModel.maxCustomFeeRate?.toDouble();
double? customFeeRate = isBitcoinWallet ? sendViewModel.customBitcoinFeeRate.toDouble() : null;
await showPopUp<void>(
@ -689,6 +690,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
sendViewModel.displayFeeRate(priority, customFeeRate?.round()),
selectedAtIndex: selectedIdx,
customItemIndex: customItemIndex,
maxValue: maxCustomFeeRate,
title: S.of(context).please_select,
headerEnabled: !isBitcoinWallet,
closeOnItemSelected: !isBitcoinWallet,

View file

@ -37,6 +37,7 @@ class OtherSettingsPage extends BasePage {
customItemIndex: _otherSettingsViewModel.customPriorityItemIndex,
onItemSelected: _otherSettingsViewModel.onDisplayBitcoinPrioritySelected,
customValue: _otherSettingsViewModel.customBitcoinFeeRate,
maxValue: _otherSettingsViewModel.maxCustomFeeRate?.toDouble(),
) :
SettingsPickerCell(
title: S.current.settings_fee_priority,

View file

@ -15,6 +15,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
this.isGridView = false,
this.matchingCriteria,
this.customValue,
this.maxValue,
this.customItemIndex,
this.onItemSelected})
: super(
@ -34,6 +35,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
displayItem: (ItemType item) => displayItem!(item, sliderValue.round()),
selectedAtIndex: selectedAtIndex,
customItemIndex: customItemIndex,
maxValue: maxValue,
headerEnabled: false,
closeOnItemSelected: false,
mainAxisAlignment: MainAxisAlignment.center,
@ -61,6 +63,7 @@ class SettingsPriorityPickerCell<ItemType> extends StandardListRow {
final bool isGridView;
final bool Function(ItemType, String)? matchingCriteria;
double? customValue;
double? maxValue;
int? customItemIndex;
@override

View file

@ -10,6 +10,7 @@ class StandardPickerListItem<T> extends TransactionDetailsListItem {
required this.onItemSelected,
required this.selectedIdx,
required this.customItemIndex,
this.maxValue,
required this.customValue})
: super(title: title, value: value);
@ -18,6 +19,7 @@ class StandardPickerListItem<T> extends TransactionDetailsListItem {
final Function(double) onSliderChanged;
final Function(T) onItemSelected;
final int selectedIdx;
final double? maxValue;
final int customItemIndex;
double customValue;
}

View file

@ -74,6 +74,7 @@ class RBFDetailsPage extends BasePage {
selectedIdx: item.selectedIdx,
customItemIndex: item.customItemIndex,
customValue: item.customValue,
maxValue: item.maxValue,
);
}

View file

@ -27,14 +27,21 @@ class Picker<Item> extends StatefulWidget {
this.headerEnabled = true,
this.closeOnItemSelected = true,
this.sliderValue,
this.minValue,
this.maxValue,
this.customItemIndex,
this.isWrapped = true,
this.borderColor,
this.onSliderChanged,
this.matchingCriteria,
}) : assert(hintText == null ||
matchingCriteria !=
null); // make sure that if the search field is enabled then there is a searching criteria provided
}) : assert(hintText == null || matchingCriteria != null) {
// make sure that if the search field is enabled then there is a searching criteria provided
if (sliderValue != null && maxValue != null) {
if (sliderValue! > maxValue!) {
sliderValue = maxValue;
}
}
}
final int selectedAtIndex;
final List<Item> items;
@ -49,12 +56,14 @@ class Picker<Item> extends StatefulWidget {
final String? hintText;
final bool headerEnabled;
final bool closeOnItemSelected;
final double? sliderValue;
double? sliderValue;
final double? minValue;
final int? customItemIndex;
final bool isWrapped;
final Color? borderColor;
final Function(double)? onSliderChanged;
final bool Function(Item, String)? matchingCriteria;
final double? maxValue;
@override
_PickerState<Item> createState() => _PickerState<Item>(items, images, onItemSelected);
@ -211,8 +220,9 @@ class _PickerState<Item> extends State<Picker<Item>> {
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor,
color: Theme.of(context)
.extension<CakeTextTheme>()!
.titleColor,
),
),
)
@ -491,8 +501,8 @@ class _PickerState<Item> extends State<Picker<Item>> {
child: Slider(
value: widget.sliderValue ?? 1,
onChanged: isActivated ? widget.onSliderChanged : null,
min: 1,
max: 100,
min: widget.minValue ?? 1,
max: widget.maxValue ?? 100,
divisions: 100,
),
),

View file

@ -15,6 +15,7 @@ class StandardPickerList<T> extends StatefulWidget {
required this.selectedIdx,
required this.customItemIndex,
required this.customValue,
this.maxValue,
}) : super(key: key);
final String title;
@ -26,6 +27,7 @@ class StandardPickerList<T> extends StatefulWidget {
final String value;
final int selectedIdx;
final double customValue;
final double? maxValue;
@override
_StandardPickerListState<T> createState() => _StandardPickerListState<T>();
@ -59,6 +61,7 @@ class _StandardPickerListState<T> extends State<StandardPickerList<T>> {
displayItem: adaptedDisplayItem,
selectedAtIndex: selectedIdx,
customItemIndex: widget.customItemIndex,
maxValue: widget.maxValue,
headerEnabled: false,
closeOnItemSelected: false,
mainAxisAlignment: MainAxisAlignment.center,

View file

@ -166,6 +166,13 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return null;
}
int? get maxCustomFeeRate {
if (wallet.type == WalletType.bitcoin) {
return bitcoin!.getMaxCustomFeeRate(wallet);
}
return null;
}
@computed
int get customBitcoinFeeRate => _settingsStore.customBitcoinFeeRate;

View file

@ -140,6 +140,13 @@ abstract class OtherSettingsViewModelBase with Store {
return customItem != null ? priorities.indexOf(customItem) : null;
}
int? get maxCustomFeeRate {
if (_wallet.type == WalletType.bitcoin) {
return bitcoin!.getMaxCustomFeeRate(_wallet);
}
return null;
}
@action
ProviderType onBuyProviderTypeSelected(ProviderType buyProviderType) =>
_settingsStore.defaultBuyProviders[walletType] = buyProviderType;

View file

@ -348,12 +348,14 @@ abstract class TransactionDetailsViewModelBase with Store {
final customItem = priorities.firstWhereOrNull(
(element) => element == sendViewModel.bitcoinTransactionPriorityCustom);
final customItemIndex = customItem != null ? priorities.indexOf(customItem) : null;
final maxCustomFeeRate = sendViewModel.maxCustomFeeRate?.toDouble();
RBFListItems.add(StandardPickerListItem(
title: S.current.estimated_new_fee,
value: bitcoin!.formatterBitcoinAmountToString(amount: newFee) + ' ${walletTypeToCryptoCurrency(wallet.type)}',
items: priorityForWalletType(wallet.type),
customValue: settingsStore.customBitcoinFeeRate.toDouble(),
maxValue: maxCustomFeeRate,
selectedIdx: selectedItem,
customItemIndex: customItemIndex ?? 0,
displayItem: (dynamic priority, double sliderValue) =>

View file

@ -159,6 +159,7 @@ abstract class Bitcoin {
Future<bool> isChangeSufficientForFee(Object wallet, String txId, String newFee);
int getFeeAmountForPriority(Object wallet, TransactionPriority priority, int inputsCount, int outputsCount, {int? size});
int getFeeAmountWithFeeRate(Object wallet, int feeRate, int inputsCount, int outputsCount, {int? size});
int getMaxCustomFeeRate(Object wallet);
}
""";