mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-25 03:56:01 +00:00
Merge CW-62
Add Haven Fee Estimate flow Deduct fee from fiat amount
This commit is contained in:
parent
ee08fe77c1
commit
c7ce849924
12 changed files with 106 additions and 51 deletions
|
@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
|
|||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
org.gradle.java.home=C:\\Program Files\\Java\\jdk1.8.0_181
|
||||
|
|
|
@ -927,6 +927,25 @@ extern "C"
|
|||
return static_cast<int32_t>(rates.size());
|
||||
}
|
||||
|
||||
uint64_t estimate_transaction_fee(int outputs, uint8_t priority_raw)
|
||||
{
|
||||
// estimateTransactionFee only cares about the number of outputs
|
||||
std::vector<std::pair<std::string, uint64_t>> destinations;
|
||||
for (int i = 0; i < outputs; i++) {
|
||||
destinations.push_back({"", 0});
|
||||
}
|
||||
auto priority = static_cast<Monero::PendingTransaction::Priority>(priority_raw);
|
||||
|
||||
try {
|
||||
return m_wallet->estimateTransactionFee(destinations, priority);
|
||||
}
|
||||
catch (...) {
|
||||
// estimateTransactionFee can throw an exception if there is a problem with the
|
||||
// network request. We must catch it here because exceptions don't propagate to Dart.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -137,4 +137,8 @@ typedef get_rate = Pointer<Int64> Function();
|
|||
|
||||
typedef size_of_rate = Int32 Function();
|
||||
|
||||
typedef update_rate = Void Function();
|
||||
typedef update_rate = Void Function();
|
||||
|
||||
typedef estimate_transaction_fee = Int64 Function(
|
||||
Int32 outputs,
|
||||
Int8 priorityRaw);
|
|
@ -135,4 +135,6 @@ typedef GetRate = Pointer<Int64> Function();
|
|||
|
||||
typedef SizeOfRate = int Function();
|
||||
|
||||
typedef UpdateRate = void Function();
|
||||
typedef UpdateRate = void Function();
|
||||
|
||||
typedef EstimateTransactionFee = int Function(int, int);
|
|
@ -8,7 +8,6 @@ import 'package:cw_haven/api/types.dart';
|
|||
import 'package:cw_haven/api/haven_api.dart';
|
||||
import 'package:cw_haven/api/exceptions/setup_wallet_exception.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
int _boolToInt(bool value) => value ? 1 : 0;
|
||||
|
||||
|
@ -116,6 +115,10 @@ final rescanBlockchainAsyncNative = havenApi
|
|||
.lookup<NativeFunction<rescan_blockchain>>('rescan_blockchain')
|
||||
.asFunction<RescanBlockchainAsync>();
|
||||
|
||||
final estimateTransactionFeeNative = havenApi
|
||||
.lookup<NativeFunction<estimate_transaction_fee>>('estimate_transaction_fee')
|
||||
.asFunction<EstimateTransactionFee>();
|
||||
|
||||
int getSyncingHeight() => getSyncingHeightNative();
|
||||
|
||||
bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
|
||||
|
@ -346,3 +349,18 @@ Future<bool> isConnected() => compute(_isConnected, 0);
|
|||
Future<int> getNodeHeight() => compute(_getNodeHeight, 0);
|
||||
|
||||
void rescanBlockchainAsync() => rescanBlockchainAsyncNative();
|
||||
|
||||
int estimateTransactionFeeSync(int outputs, int priorityRaw) {
|
||||
return estimateTransactionFeeNative(outputs, priorityRaw);
|
||||
}
|
||||
|
||||
int _estimateTransactionFee(Map args) {
|
||||
final priorityRaw = args['priorityRaw'] as int;
|
||||
final outputsCount = args['outputsCount'] as int;
|
||||
|
||||
return estimateTransactionFeeSync(outputsCount, priorityRaw);
|
||||
}
|
||||
|
||||
Future<int> estimateTransactionFee({int priorityRaw, int outputsCount}) {
|
||||
return compute(_estimateTransactionFee, {'priorityRaw': priorityRaw, 'outputsCount': outputsCount});
|
||||
}
|
38
cw_haven/lib/haven_fee_estimate.dart
Normal file
38
cw_haven/lib/haven_fee_estimate.dart
Normal file
|
@ -0,0 +1,38 @@
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/fee_estimate.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_haven/api/wallet.dart' as haven_wallet;
|
||||
|
||||
part 'haven_fee_estimate.g.dart';
|
||||
|
||||
class HavenFeeEstimate = _HavenFeeEstimate with _$HavenFeeEstimate;
|
||||
|
||||
abstract class _HavenFeeEstimate extends FeeEstimate with Store {
|
||||
_HavenFeeEstimate()
|
||||
: _estimatedFee = new ObservableMap<String, int>();
|
||||
|
||||
@observable
|
||||
ObservableMap<String, int> _estimatedFee;
|
||||
|
||||
@override
|
||||
void update({TransactionPriority priority, int outputsCount}) {
|
||||
Future(() async {
|
||||
final fee = await haven_wallet.estimateTransactionFee(priorityRaw: priority.raw, outputsCount: outputsCount);
|
||||
set(priority: priority, fee: fee, outputsCount: outputsCount);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
int get({TransactionPriority priority, int amount, int outputsCount}) {
|
||||
return _estimatedFee[_key(priority, outputsCount)] ?? 0;
|
||||
}
|
||||
|
||||
@override
|
||||
void set({TransactionPriority priority, int outputsCount, int fee}) {
|
||||
_estimatedFee[_key(priority, outputsCount)] = fee;
|
||||
}
|
||||
|
||||
String _key(TransactionPriority priority, int outputsCount) {
|
||||
return "$priority:$outputsCount";
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_haven/haven_transaction_creation_exception.dart';
|
||||
|
@ -26,8 +25,8 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/monero_transaction_priority.dart';
|
||||
import 'package:cw_haven/haven_balance.dart';
|
||||
import 'package:cw_haven/haven_fee_estimate.dart';
|
||||
|
||||
part 'haven_wallet.g.dart';
|
||||
|
||||
|
@ -49,10 +48,14 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
balance.addAll(getHavenBalance(accountIndex: account.id));
|
||||
walletAddresses.updateSubaddressList(accountIndex: account.id);
|
||||
});
|
||||
feeEstimate = HavenFeeEstimate();
|
||||
}
|
||||
|
||||
static const int _autoSaveInterval = 30;
|
||||
|
||||
@override
|
||||
HavenFeeEstimate feeEstimate;
|
||||
|
||||
@override
|
||||
HavenWalletAddresses walletAddresses;
|
||||
|
||||
|
@ -211,28 +214,6 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
return PendingHavenTransaction(pendingTransactionDescription, assetType);
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount) {
|
||||
// FIXME: hardcoded value;
|
||||
|
||||
if (priority is MoneroTransactionPriority) {
|
||||
switch (priority) {
|
||||
case MoneroTransactionPriority.slow:
|
||||
return 24590000;
|
||||
case MoneroTransactionPriority.regular:
|
||||
return 123050000;
|
||||
case MoneroTransactionPriority.medium:
|
||||
return 245029999;
|
||||
case MoneroTransactionPriority.fast:
|
||||
return 614530000;
|
||||
case MoneroTransactionPriority.fastest:
|
||||
return 26021600000;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> save() async {
|
||||
await walletAddresses.updateAddressesInBox();
|
||||
|
|
|
@ -15,7 +15,6 @@ import 'package:cake_wallet/store/settings_store.dart';
|
|||
import 'package:cake_wallet/core/fiat_conversion_service.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||
|
||||
ReactionDisposer _onCurrentWalletChangeReaction;
|
||||
ReactionDisposer _onCurrentWalletChangeFiatRateUpdateReaction;
|
||||
|
@ -53,7 +52,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
|||
wallet) async {
|
||||
try {
|
||||
final node = settingsStore.getCurrentNode(wallet.type);
|
||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore, settingsStore);
|
||||
startCheckConnectionReaction(wallet, settingsStore);
|
||||
await getIt
|
||||
.get<SharedPreferences>()
|
||||
|
|
|
@ -2,17 +2,14 @@ import 'package:cake_wallet/di.dart';
|
|||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||
import 'package:cake_wallet/entities/wake_lock.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_monero/monero_transaction_priority.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
ReactionDisposer _onWalletSyncStatusChangeReaction;
|
||||
|
||||
|
|
|
@ -265,7 +265,6 @@ class SendCardState extends State<SendCard>
|
|||
child: InkWell(
|
||||
onTap: () {
|
||||
output.setSendAll();
|
||||
cryptoAmountController.text = sendViewModel.balance;
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
|
@ -557,10 +556,13 @@ class SendCardState extends State<SendCard>
|
|||
|
||||
reaction((_) => output.fiatAmount, (String amount) {
|
||||
if (amount != fiatAmountController.text) {
|
||||
fiatAmountController.text = amount;
|
||||
// final doubleAmount = double.tryParse(amount) ?? 0;
|
||||
// final doubleFee = double.tryParse(sendViewModel.estimatedFiatFee(sendViewModel.balance)) ?? 0;
|
||||
// fiatAmountController.text = doubleAmount - doubleFee > 0 ? "${doubleAmount - doubleFee}" : "0.00";
|
||||
if (sendViewModel.outputs[0].sendAll) {
|
||||
final doubleAmount = double.tryParse(amount) ?? 0;
|
||||
final doubleFee = sendViewModel.estimatedFee;
|
||||
fiatAmountController.text = doubleAmount - doubleFee > 0 ? "${doubleAmount - doubleFee}" : "0.00";
|
||||
} else {
|
||||
fiatAmountController.text = amount;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ abstract class OutputBase with Store {
|
|||
|
||||
int _estimateAmountAll() {
|
||||
final fee = _wallet.feeEstimate.get(priority: _settingsStore.priority[_wallet.type], outputsCount: 1);
|
||||
return max(0, _wallet.balance.available - fee);
|
||||
return max(0, _wallet.balance[cryptoCurrencyHandler()].available - fee);
|
||||
}
|
||||
|
||||
Future<void> fetchParsedAddress(BuildContext context) async {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'package:cake_wallet/core/amount_converter.dart';
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/format_amount.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
|
@ -58,6 +56,8 @@ abstract class SendViewModelBase with Store {
|
|||
_settingsStore.priority.observe((change) async {
|
||||
_wallet.feeEstimate.update(priority: change.newValue, outputsCount: outputs.length);
|
||||
});
|
||||
|
||||
estimateFee();
|
||||
}
|
||||
|
||||
@observable
|
||||
|
@ -166,16 +166,6 @@ abstract class SendViewModelBase with Store {
|
|||
|
||||
bool get hasCurrecyChanger => walletType == WalletType.haven;
|
||||
|
||||
int estimatedFee(String amount) {
|
||||
return _wallet.calculateEstimatedFee(_settingsStore.priority[_wallet.type], AmountConverter.amountStringToInt(
|
||||
selectedCryptoCurrency, amount));
|
||||
}
|
||||
|
||||
String estimatedFiatFee(String amount) {
|
||||
return _calculateFiatAmount(AmountConverter.amountIntToString(
|
||||
selectedCryptoCurrency, estimatedFee(amount)));
|
||||
}
|
||||
|
||||
final WalletBase _wallet;
|
||||
final SettingsStore _settingsStore;
|
||||
final SendTemplateViewModel sendTemplateViewModel;
|
||||
|
@ -286,7 +276,11 @@ abstract class SendViewModelBase with Store {
|
|||
totalFormattedCryptoAmount += output.formattedCryptoAmount;
|
||||
}
|
||||
|
||||
final fee = _wallet.feeEstimate.get(priority: _settingsStore.priority[_wallet.type], amount: totalFormattedCryptoAmount, outputsCount: outputs.length);
|
||||
final fee = _wallet.feeEstimate.get(
|
||||
priority: _settingsStore.priority[_wallet.type],
|
||||
amount: totalFormattedCryptoAmount,
|
||||
outputsCount: outputs.length,
|
||||
);
|
||||
|
||||
return formatAmountToDouble(type: _wallet.type, amount: fee);
|
||||
} catch (e) {
|
||||
|
|
Loading…
Reference in a new issue