mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-31 02:39:08 -04:00
Fix fee calculation, add adjustable non-trade mining fee
This commit is contained in:
parent
2abc2cd5bc
commit
565c44d94c
12 changed files with 230 additions and 144 deletions
|
@ -186,7 +186,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
new Popup().warning("You have already at least one address which is not used yet in any transaction.\n" +
|
||||
"Please select in the address table an unused address.").show();
|
||||
} else {
|
||||
AddressEntry newSavingsAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE);
|
||||
AddressEntry newSavingsAddressEntry = walletService.createAddressEntry(AddressEntry.Context.AVAILABLE);
|
||||
updateList();
|
||||
observableList.stream()
|
||||
.filter(depositListItem -> depositListItem.getAddressString().equals(newSavingsAddressEntry.getAddressString()))
|
||||
|
|
|
@ -196,10 +196,10 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
};
|
||||
try {
|
||||
Coin requiredFee = walletService.getRequiredFeeForMultipleAddresses(fromAddresses,
|
||||
withdrawToTextField.getText(), senderAmount, null);
|
||||
withdrawToTextField.getText(), senderAmount);
|
||||
Coin receiverAmount = senderAmount.subtract(requiredFee);
|
||||
if (BitsquareApp.DEV_MODE) {
|
||||
doWithdraw(senderAmount, callback);
|
||||
doWithdraw(receiverAmount, callback);
|
||||
} else {
|
||||
new Popup().headLine("Confirm withdrawal request")
|
||||
.confirmation("Sending: " + formatter.formatCoinWithCode(senderAmount) + "\n" +
|
||||
|
|
|
@ -408,7 +408,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
//noinspection SimplifiableIfStatement
|
||||
if (amountAsCoin.get() != null && offer != null) {
|
||||
Coin customAmount = offer.getAmount().subtract(amountAsCoin.get());
|
||||
Coin dustAndFee = FeePolicy.getFeePerKb().add(Transaction.MIN_NONDUST_OUTPUT);
|
||||
Coin dustAndFee = FeePolicy.getFixedTxFeeForTrades().add(Transaction.MIN_NONDUST_OUTPUT);
|
||||
return customAmount.isPositive() && customAmount.isLessThan(dustAndFee);
|
||||
} else {
|
||||
return true;
|
||||
|
|
|
@ -186,9 +186,11 @@ public abstract class Overlay<T extends Overlay> {
|
|||
Scene rootScene = owner.getScene();
|
||||
if (rootScene != null) {
|
||||
Window window = rootScene.getWindow();
|
||||
window.xProperty().removeListener(positionListener);
|
||||
window.yProperty().removeListener(positionListener);
|
||||
window.widthProperty().removeListener(positionListener);
|
||||
if (window != null && positionListener != null) {
|
||||
window.xProperty().removeListener(positionListener);
|
||||
window.yProperty().removeListener(positionListener);
|
||||
window.widthProperty().removeListener(positionListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,12 +147,12 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
((SellerTrade) getTrade()).onFiatPaymentReceived(resultHandler, errorMessageHandler);
|
||||
}
|
||||
|
||||
public void onWithdrawRequest(String toAddress, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
public void onWithdrawRequest(String toAddress, Coin receiverAmount, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
checkNotNull(getTrade(), "trade must not be null");
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
walletPasswordWindow.onAesKey(aesKey -> doWithdrawRequest(toAddress, aesKey, resultHandler, faultHandler)).show();
|
||||
walletPasswordWindow.onAesKey(aesKey -> doWithdrawRequest(toAddress, receiverAmount, aesKey, resultHandler, faultHandler)).show();
|
||||
} else
|
||||
doWithdrawRequest(toAddress, null, resultHandler, faultHandler);
|
||||
doWithdrawRequest(toAddress, receiverAmount, null, resultHandler, faultHandler);
|
||||
}
|
||||
|
||||
public void onOpenDispute() {
|
||||
|
@ -279,10 +279,11 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
selectedItemProperty.set(item);
|
||||
}
|
||||
|
||||
private void doWithdrawRequest(String toAddress, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
private void doWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
if (toAddress != null && toAddress.length() > 0) {
|
||||
tradeManager.onWithdrawRequest(
|
||||
toAddress,
|
||||
receiverAmount,
|
||||
aesKey,
|
||||
getTrade(),
|
||||
() -> {
|
||||
|
|
|
@ -168,19 +168,20 @@ public class BuyerStep5View extends TradeStepView {
|
|||
// TODO at some error situation it can be tha the funds are already paid out and we get stuck here
|
||||
// need handling to remove the trade (planned for next release)
|
||||
Coin balance = walletService.getBalanceForAddress(fromAddressesEntry.getAddress());
|
||||
if (balance.isZero()) {
|
||||
new Popup().warning("Your funds have already been withdrawn.\nPlease check the transaction history.").show();
|
||||
model.dataModel.tradeManager.addTradeToClosedTrades(trade);
|
||||
} else {
|
||||
if (toAddresses.isEmpty()) {
|
||||
validateWithdrawAddress();
|
||||
} else if (Restrictions.isAboveFixedTxFeeAndDust(senderAmount)) {
|
||||
try {
|
||||
try {
|
||||
Coin requiredFee = walletService.getRequiredFee(fromAddresses, toAddresses, senderAmount, AddressEntry.Context.TRADE_PAYOUT);
|
||||
Coin receiverAmount = senderAmount.subtract(requiredFee);
|
||||
if (balance.isZero()) {
|
||||
new Popup().warning("Your funds have already been withdrawn.\nPlease check the transaction history.").show();
|
||||
model.dataModel.tradeManager.addTradeToClosedTrades(trade);
|
||||
} else {
|
||||
if (toAddresses.isEmpty()) {
|
||||
validateWithdrawAddress();
|
||||
} else if (Restrictions.isAboveFixedTxFeeAndDust(senderAmount)) {
|
||||
|
||||
if (BitsquareApp.DEV_MODE) {
|
||||
doWithdrawal();
|
||||
doWithdrawal(receiverAmount);
|
||||
} else {
|
||||
Coin requiredFee = walletService.getRequiredFee(fromAddresses, toAddresses, senderAmount, null, AddressEntry.Context.TRADE_PAYOUT);
|
||||
Coin receiverAmount = senderAmount.subtract(requiredFee);
|
||||
BSFormatter formatter = model.formatter;
|
||||
String key = "reviewWithdrawalAtTradeComplete";
|
||||
if (!BitsquareApp.DEV_MODE && preferences.showAgain(key)) {
|
||||
|
@ -197,34 +198,34 @@ public class BuyerStep5View extends TradeStepView {
|
|||
withdrawToExternalWalletButton.setDisable(false);
|
||||
})
|
||||
.actionButtonText("Yes")
|
||||
.onAction(() -> doWithdrawal())
|
||||
.onAction(() -> doWithdrawal(receiverAmount))
|
||||
.dontShowAgainId(key, preferences)
|
||||
.show();
|
||||
} else {
|
||||
doWithdrawal();
|
||||
doWithdrawal(receiverAmount);
|
||||
}
|
||||
}
|
||||
} catch (AddressFormatException e) {
|
||||
validateWithdrawAddress();
|
||||
} catch (AddressEntryException e) {
|
||||
log.error(e.getMessage());
|
||||
|
||||
} else {
|
||||
new Popup()
|
||||
.warning("The amount to transfer is lower than the transaction fee and the min. possible tx value (dust).")
|
||||
.show();
|
||||
}
|
||||
} else {
|
||||
new Popup()
|
||||
.warning("The amount to transfer is lower than the transaction fee and the min. possible tx value (dust).")
|
||||
.show();
|
||||
}
|
||||
} catch (AddressFormatException e) {
|
||||
validateWithdrawAddress();
|
||||
} catch (AddressEntryException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void doWithdrawal() {
|
||||
private void doWithdrawal(Coin receiverAmount) {
|
||||
useSavingsWalletButton.setDisable(true);
|
||||
withdrawToExternalWalletButton.setDisable(true);
|
||||
|
||||
model.dataModel.onWithdrawRequest(withdrawAddressTextField.getText(),
|
||||
() -> {
|
||||
handleTradeCompleted();
|
||||
},
|
||||
receiverAmount,
|
||||
this::handleTradeCompleted,
|
||||
(errorMessage, throwable) -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
|
|
|
@ -31,8 +31,6 @@ import io.bitsquare.gui.util.Layout;
|
|||
import io.bitsquare.locale.*;
|
||||
import io.bitsquare.user.BlockChainExplorer;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -44,6 +42,7 @@ import javafx.scene.layout.AnchorPane;
|
|||
import javafx.scene.layout.GridPane;
|
||||
import javafx.util.Callback;
|
||||
import javafx.util.StringConverter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -61,7 +60,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
|
||||
private CheckBox useAnimationsCheckBox, autoSelectArbitratorsCheckBox, showOwnOffersInOfferBook;
|
||||
private int gridRow = 0;
|
||||
//private InputTextField transactionFeeInputTextField;
|
||||
private InputTextField transactionFeeInputTextField;
|
||||
private ChangeListener<Boolean> transactionFeeFocusedListener;
|
||||
private final Preferences preferences;
|
||||
private BSFormatter formatter;
|
||||
|
@ -75,7 +74,6 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
final ObservableList<String> btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
|
||||
final ObservableList<BlockChainExplorer> blockExplorers;
|
||||
final ObservableList<String> languageCodes;
|
||||
final StringProperty transactionFeePerByte = new SimpleStringProperty();
|
||||
public final ObservableList<FiatCurrency> fiatCurrencies;
|
||||
public final ObservableList<FiatCurrency> allFiatCurrencies;
|
||||
public final ObservableList<CryptoCurrency> cryptoCurrencies;
|
||||
|
@ -288,7 +286,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
}
|
||||
|
||||
private void initializeOtherOptions() {
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 3, "General preferences", Layout.GROUP_DISTANCE);
|
||||
TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 4, "General preferences", Layout.GROUP_DISTANCE);
|
||||
GridPane.setColumnSpan(titledGroupBg, 4);
|
||||
// userLanguageComboBox = addLabelComboBox(root, gridRow, "Language:", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
// btcDenominationComboBox = addLabelComboBox(root, ++gridRow, "Bitcoin denomination:").second;
|
||||
|
@ -313,11 +311,21 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
UserThread.runAfter(() -> deviationInputTextField.setText(formatter.formatToPercent(preferences.getMaxPriceDistanceInPercent())), 100, TimeUnit.MILLISECONDS);
|
||||
};
|
||||
|
||||
// TODO need a bit extra work to separate trade and non trade tx fees before it can be used
|
||||
/*transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeInputTextField = addLabelInputTextField(root, ++gridRow, "Transaction fee (satoshi/byte):").second;
|
||||
transactionFeeFocusedListener = (o, oldValue, newValue) -> {
|
||||
onFocusOutTransactionFeeTextField(oldValue, newValue);
|
||||
};*/
|
||||
if (oldValue && !newValue) {
|
||||
try {
|
||||
int val = Integer.parseInt(transactionFeeInputTextField.getText());
|
||||
preferences.setNonTradeTxFeePerKB(val * 1000);
|
||||
} catch (NumberFormatException t) {
|
||||
new Popup().warning("Please enter integer numbers only.").show();
|
||||
transactionFeeInputTextField.setText(getNonTradeTxFeePerKB());
|
||||
} catch (Throwable t) {
|
||||
new Popup().warning("Your input was not accepted.\n" + t.getMessage()).show();
|
||||
transactionFeeInputTextField.setText(getNonTradeTxFeePerKB());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initializeDisplayOptions() {
|
||||
|
@ -378,7 +386,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
}
|
||||
|
||||
private void activateOtherOptions() {
|
||||
transactionFeePerByte.set(String.valueOf(preferences.getTxFeePerKB() / 1000));
|
||||
transactionFeeInputTextField.setText(getNonTradeTxFeePerKB());
|
||||
|
||||
/* btcDenominationComboBox.setDisable(true);
|
||||
btcDenominationComboBox.setItems(btcDenominations);
|
||||
|
@ -423,8 +431,12 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
deviationInputTextField.textProperty().addListener(deviationListener);
|
||||
deviationInputTextField.focusedProperty().addListener(deviationFocusedListener);
|
||||
|
||||
// transactionFeeInputTextField.textProperty().bindBidirectional(transactionFeePerByte);
|
||||
// transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
|
||||
transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getNonTradeTxFeePerKB() {
|
||||
return String.valueOf(preferences.getNonTradeTxFeePerKB() / 1000);
|
||||
}
|
||||
|
||||
private void activateDisplayPreferences() {
|
||||
|
@ -454,8 +466,7 @@ public class PreferencesView extends ActivatableViewAndModel<GridPane, Activatab
|
|||
blockChainExplorerComboBox.setOnAction(null);
|
||||
deviationInputTextField.textProperty().removeListener(deviationListener);
|
||||
deviationInputTextField.focusedProperty().removeListener(deviationFocusedListener);
|
||||
// transactionFeeInputTextField.textProperty().unbind();
|
||||
/// transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
|
||||
transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue