Make max trade limit dependent on payment method. increase limits to 0.1-0.2 btc

This commit is contained in:
Manfred Karrer 2016-03-10 18:47:53 +01:00
parent 44445cd411
commit 4010f5a727
26 changed files with 140 additions and 130 deletions

View File

@ -62,7 +62,7 @@ public class FeePolicy {
// Some wallets (Mycelium) don't support higher fees
public static Coin getMinRequiredFeeForFundingTx() {
return Coin.valueOf(20_000);
return Coin.valueOf(20_000);
}
@ -78,17 +78,8 @@ public class FeePolicy {
}
// TODO make final again later 100_000_000
// 0.1 BTC; about 4 EUR @ 400 EUR/BTC
private static Coin SECURITY_DEPOSIT = Coin.valueOf(10_000_000);
public static Coin getSecurityDeposit() {
return SECURITY_DEPOSIT;
}
// Called from WalletService to reduce SECURITY_DEPOSIT for mainnet to 0.01 btc
// TODO remove later when tested enough
public static void setSecurityDeposit(Coin securityDeposit) {
SECURITY_DEPOSIT = securityDeposit;
return Coin.valueOf(10_000_000);
}
}

View File

@ -22,18 +22,8 @@ import org.bitcoinj.core.Transaction;
public class Restrictions {
// TODO make final again later
public static final Coin MIN_TRADE_AMOUNT = Coin.parseCoin("0.0001"); // 4 cent @ 400 EUR/BTC
// TODO make final again later
public static Coin MAX_TRADE_AMOUNT = Coin.parseCoin("1");
// Called from WalletService to reduce MAX_TRADE_AMOUNT for mainnet to 0.01 btc
// TODO remove later when tested enough
public static void setMaxTradeAmount(Coin maxTradeAmount) {
MAX_TRADE_AMOUNT = maxTradeAmount;
}
public static boolean isAboveFixedTxFeeAndDust(Coin amount) {
return amount != null && amount.compareTo(FeePolicy.getFixedTxFeeForTrades().add(Transaction.MIN_NONDUST_OUTPUT)) > 0;
}

View File

@ -213,12 +213,6 @@ public class WalletService {
walletAppKit.connectToLocalHost(); // You should run a regtest mode bitcoind locally.}
}
} else if (params == MainNetParams.get()) {
// reduce for mainnet testing
// TODO revert later when tested enough
FeePolicy.setSecurityDeposit(Coin.parseCoin("0.01")); // 4 EUR @ 400 EUR/BTC
Restrictions.setMaxTradeAmount(Coin.parseCoin("0.1")); // 40 EUR @ 400 EUR/BTC
// Checkpoints are block headers that ship inside our app: for a new user, we pick the last header
// in the checkpoints file and then download the rest from the network. It makes things much faster.
// Checkpoint files are made using the BuildCheckpoints tool and usually we have to download the

View File

@ -19,10 +19,12 @@ package io.bitsquare.payment;
import io.bitsquare.app.Version;
import io.bitsquare.common.persistance.Persistable;
import org.bitcoinj.core.Coin;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -65,39 +67,56 @@ public final class PaymentMethod implements Persistable, Comparable {
public static PaymentMethod BLOCK_CHAINS;
public static final List<PaymentMethod> ALL_VALUES = new ArrayList<>(Arrays.asList(
OK_PAY = new PaymentMethod(OK_PAY_ID, 0, DAY), // tx instant so min. wait time
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, 0, DAY),
SEPA = new PaymentMethod(SEPA_ID, 0, 8 * DAY), // sepa takes 1-3 business days. We use 8 days to include safety for holidays
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 0, 4 * DAY),
SAME_BANK = new PaymentMethod(SAME_BANK_ID, 0, 2 * DAY),
SPECIFIC_BANKS = new PaymentMethod(SPECIFIC_BANKS_ID, 0, 4 * DAY),
SWISH = new PaymentMethod(SWISH_ID, 0, DAY),
ALI_PAY = new PaymentMethod(ALI_PAY_ID, 0, DAY),
/* FED_WIRE = new PaymentMethod(FED_WIRE_ID, 0, DAY),*/
/* TRANSFER_WISE = new PaymentMethod(TRANSFER_WISE_ID, 0, DAY),*/
/* US_POSTAL_MONEY_ORDER = new PaymentMethod(US_POSTAL_MONEY_ORDER_ID, 0, DAY),*/
BLOCK_CHAINS = new PaymentMethod(BLOCK_CHAINS_ID, 0, DAY)
OK_PAY = new PaymentMethod(OK_PAY_ID, 0, DAY, Coin.parseCoin("0.5")), // tx instant so min. wait time
PERFECT_MONEY = new PaymentMethod(PERFECT_MONEY_ID, 0, DAY, Coin.parseCoin("0.2")),
SEPA = new PaymentMethod(SEPA_ID, 0, 8 * DAY, Coin.parseCoin("0.1")), // sepa takes 1-3 business days. We use 8 days to include safety for holidays
NATIONAL_BANK = new PaymentMethod(NATIONAL_BANK_ID, 0, 4 * DAY, Coin.parseCoin("0.1")),
SAME_BANK = new PaymentMethod(SAME_BANK_ID, 0, 2 * DAY, Coin.parseCoin("0.1")),
SPECIFIC_BANKS = new PaymentMethod(SPECIFIC_BANKS_ID, 0, 4 * DAY, Coin.parseCoin("0.1")),
SWISH = new PaymentMethod(SWISH_ID, 0, DAY, Coin.parseCoin("0.2")),
ALI_PAY = new PaymentMethod(ALI_PAY_ID, 0, DAY, Coin.parseCoin("0.2")),
/* FED_WIRE = new PaymentMethod(FED_WIRE_ID, 0, DAY, Coin.parseCoin("0.1")),*/
/* TRANSFER_WISE = new PaymentMethod(TRANSFER_WISE_ID, 0, DAY, Coin.parseCoin("0.1")),*/
/* US_POSTAL_MONEY_ORDER = new PaymentMethod(US_POSTAL_MONEY_ORDER_ID, 0, DAY, Coin.parseCoin("0.1")),*/
BLOCK_CHAINS = new PaymentMethod(BLOCK_CHAINS_ID, 0, DAY, Coin.parseCoin("0.2"))
));
private final String id;
private final long lockTime;
private long lockTime;
private final int maxTradePeriod;
private int maxTradePeriod;
private Coin maxTradeLimitInBitcoin;
/**
* @param id
* @param lockTime lock time when seller release BTC until the payout tx gets valid (bitcoin tx lockTime). Serves as protection
* against charge back risk. If Bank do the charge back quickly the Arbitrator and the seller can push another
* double spend tx to invalidate the time locked payout tx. For the moment we set all to 0 but will have it in
* place when needed.
* @param maxTradePeriod The min. period a trader need to wait until he gets displayed the contact form for opening a dispute.
* @param lockTime lock time when seller release BTC until the payout tx gets valid (bitcoin tx lockTime). Serves as protection
* against charge back risk. If Bank do the charge back quickly the Arbitrator and the seller can push another
* double spend tx to invalidate the time locked payout tx. For the moment we set all to 0 but will have it in
* place when needed.
* @param maxTradePeriod The min. period a trader need to wait until he gets displayed the contact form for opening a dispute.
* @param maxTradeLimitInBitcoin The max. allowed trade amount in Bitcoin for that payment method (depending on charge back risk)
*/
public PaymentMethod(String id, long lockTime, int maxTradePeriod) {
public PaymentMethod(String id, long lockTime, int maxTradePeriod, Coin maxTradeLimitInBitcoin) {
this.id = id;
this.lockTime = lockTime;
this.maxTradePeriod = maxTradePeriod;
this.maxTradeLimitInBitcoin = maxTradeLimitInBitcoin;
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
// In case we update those values we want that the persisted accounts get updated as well
PaymentMethod paymentMethod = PaymentMethod.getPaymentMethodById(id);
this.lockTime = paymentMethod.getLockTime();
this.maxTradePeriod = paymentMethod.getMaxTradePeriod();
this.maxTradeLimitInBitcoin = paymentMethod.getMaxTradeLimitInBitcoin();
} catch (Throwable t) {
log.error("Cannot be deserialized." + t.getMessage());
}
}
public static PaymentMethod getPaymentMethodById(String name) {
@ -116,6 +135,10 @@ public final class PaymentMethod implements Persistable, Comparable {
return lockTime;
}
public Coin getMaxTradeLimitInBitcoin() {
return maxTradeLimitInBitcoin;
}
@Override
public int compareTo(@NotNull Object other) {
if (id != null)
@ -133,7 +156,8 @@ public final class PaymentMethod implements Persistable, Comparable {
if (lockTime != that.lockTime) return false;
if (maxTradePeriod != that.maxTradePeriod) return false;
return !(id != null ? !id.equals(that.id) : that.id != null);
if (id != null ? !id.equals(that.id) : that.id != null) return false;
return !(maxTradeLimitInBitcoin != null ? !maxTradeLimitInBitcoin.equals(that.maxTradeLimitInBitcoin) : that.maxTradeLimitInBitcoin != null);
}
@ -142,6 +166,7 @@ public final class PaymentMethod implements Persistable, Comparable {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (int) (lockTime ^ (lockTime >>> 32));
result = 31 * result + maxTradePeriod;
result = 31 * result + (maxTradeLimitInBitcoin != null ? maxTradeLimitInBitcoin.hashCode() : 0);
return result;
}
@ -150,7 +175,8 @@ public final class PaymentMethod implements Persistable, Comparable {
return "PaymentMethod{" +
"id='" + id + '\'' +
", lockTime=" + lockTime +
", waitPeriodForOpenDispute=" + maxTradePeriod +
", maxTradePeriod=" + maxTradePeriod +
", maxTradeLimitInBitcoin=" + maxTradeLimitInBitcoin +
'}';
}
}

View File

@ -200,8 +200,8 @@ public final class Offer implements StoragePayload, RequiresOwnerIsOnlinePayload
checkArgument(getMinAmount().compareTo(Restrictions.MIN_TRADE_AMOUNT) >= 0, "MinAmount is less then "
+ Restrictions.MIN_TRADE_AMOUNT.toFriendlyString());
checkArgument(getAmount().compareTo(Restrictions.MAX_TRADE_AMOUNT) <= 0, "Amount is larger then "
+ Restrictions.MAX_TRADE_AMOUNT.toFriendlyString());
checkArgument(getAmount().compareTo(getPaymentMethod().getMaxTradeLimitInBitcoin()) <= 0, "Amount is larger then "
+ getPaymentMethod().getMaxTradeLimitInBitcoin().toFriendlyString());
checkArgument(getAmount().compareTo(getMinAmount()) >= 0, "MinAmount is larger then Amount");
checkArgument(getPrice().isPositive(), "Price is not a positive value");

View File

@ -983,7 +983,7 @@ textfield */
-fx-background-color: linear-gradient(to bottom, #fcfcfc, #e5e5e5);
-fx-background-radius: 5 5 5 5;
-fx-background-insets: 5 5 20 20;
-fx-effect: dropshadow(gaussian, #333, 12, 0, -1, 3);
-fx-effect: dropshadow(gaussian, #666, 12, 0, -1, 3);
}
.popup-icon-information {

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.AliPayValidator;
import io.bitsquare.gui.util.validation.InputValidator;
@ -46,8 +47,8 @@ public class AliPayForm extends PaymentMethodForm {
return gridRow;
}
public AliPayForm(PaymentAccount paymentAccount, AliPayValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
public AliPayForm(PaymentAccount paymentAccount, AliPayValidator aliPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.aliPayAccount = (AliPayAccount) paymentAccount;
this.aliPayValidator = aliPayValidator;
}

View File

@ -21,6 +21,7 @@ import io.bitsquare.common.util.Tuple2;
import io.bitsquare.common.util.Tuple3;
import io.bitsquare.common.util.Tuple4;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.*;
@ -67,8 +68,8 @@ abstract class BankForm extends PaymentMethodForm {
}
BankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.bankAccountContractData = (BankAccountContractData) paymentAccount.contractData;
}

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.AltCoinAddressValidator;
import io.bitsquare.gui.util.validation.InputValidator;
@ -57,8 +58,8 @@ public class BlockChainForm extends PaymentMethodForm {
}
public BlockChainForm(PaymentAccount paymentAccount, AltCoinAddressValidator altCoinAddressValidator, InputValidator inputValidator, GridPane gridPane,
int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.cryptoCurrencyAccount = (CryptoCurrencyAccount) paymentAccount;
this.altCoinAddressValidator = altCoinAddressValidator;
}

View File

@ -17,6 +17,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.payment.PaymentAccount;
import io.bitsquare.payment.PaymentAccountContractData;
@ -32,7 +33,7 @@ public class NationalBankForm extends BankForm {
}
public NationalBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
}
}

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.OKPayValidator;
@ -53,8 +54,8 @@ public class OKPayForm extends PaymentMethodForm {
return gridRow;
}
public OKPayForm(PaymentAccount paymentAccount, OKPayValidator okPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
public OKPayForm(PaymentAccount paymentAccount, OKPayValidator okPayValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.okPayAccount = (OKPayAccount) paymentAccount;
this.okPayValidator = okPayValidator;
}

View File

@ -19,6 +19,7 @@ package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.common.util.Tuple3;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.TradeCurrency;
@ -46,6 +47,7 @@ public abstract class PaymentMethodForm {
protected final InputValidator inputValidator;
protected final GridPane gridPane;
protected int gridRow;
private BSFormatter formatter;
protected final BooleanProperty allInputsValid = new SimpleBooleanProperty();
protected int gridRowFrom;
@ -53,11 +55,12 @@ public abstract class PaymentMethodForm {
protected CheckBox useCustomAccountNameCheckBox;
private ComboBox<TradeCurrency> currencyComboBox;
public PaymentMethodForm(PaymentAccount paymentAccount, InputValidator inputValidator, GridPane gridPane, int gridRow) {
public PaymentMethodForm(PaymentAccount paymentAccount, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
this.paymentAccount = paymentAccount;
this.inputValidator = inputValidator;
this.gridPane = gridPane;
this.gridRow = gridRow;
this.formatter = formatter;
}
protected void addTradeCurrencyComboBox() {
@ -116,24 +119,24 @@ public abstract class PaymentMethodForm {
if (hours > 24)
displayText = hours / 24 + " days";
addLabelTextField(gridPane, gridRow, "Max. allowed trade period / date:", displayText + " / " + dateFromBlocks);
}
}
protected void addAllowedPeriod() {
long hours = paymentAccount.getPaymentMethod().getMaxTradePeriod() / 6;
String displayText = hours + " hours";
String time = hours + " hours";
if (hours == 1)
displayText = "1 hour";
time = "1 hour";
else if (hours == 24)
displayText = "1 day";
time = "1 day";
else if (hours > 24)
displayText = hours / 24 + " days";
time = hours / 24 + " days";
displayText += " (Max. permitted period until the trade has to be completed)";
String displayText = "Max. trade duration: " + time + " / Max. trade limit: " +
formatter.formatCoinWithCode(paymentAccount.getPaymentMethod().getMaxTradeLimitInBitcoin());
addLabelTextField(gridPane, ++gridRow, "Max. allowed trade period:", displayText);
addLabelTextField(gridPane, ++gridRow, "Limitations:", displayText);
}
abstract protected void autoFillNameTextField();

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.PerfectMoneyValidator;
@ -47,8 +48,8 @@ public class PerfectMoneyForm extends PaymentMethodForm {
}
public PerfectMoneyForm(PaymentAccount paymentAccount, PerfectMoneyValidator perfectMoneyValidator, InputValidator inputValidator, GridPane gridPane, int
gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.perfectMoneyAccount = (PerfectMoneyAccount) paymentAccount;
this.perfectMoneyValidator = perfectMoneyValidator;
}

View File

@ -19,6 +19,7 @@ package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.common.util.Tuple2;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.payment.CountryBasedPaymentAccount;
import io.bitsquare.payment.PaymentAccount;
@ -40,8 +41,8 @@ public class SameBankForm extends BankForm {
}
public SameBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
}
@Override

View File

@ -19,6 +19,7 @@ package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.common.util.Tuple3;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.BICValidator;
import io.bitsquare.gui.util.validation.IBANValidator;
@ -26,6 +27,7 @@ import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.locale.*;
import io.bitsquare.payment.*;
import javafx.collections.FXCollections;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.control.*;
@ -63,8 +65,8 @@ public class SepaForm extends PaymentMethodForm {
}
public SepaForm(PaymentAccount paymentAccount, IBANValidator ibanValidator, BICValidator bicValidator, InputValidator inputValidator,
GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.sepaAccount = (SepaAccount) paymentAccount;
this.ibanValidator = ibanValidator;
this.bicValidator = bicValidator;
@ -152,8 +154,9 @@ public class SepaForm extends PaymentMethodForm {
private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList, List<Country> dataProvider) {
Label label = addLabel(gridPane, ++gridRow, title, 0);
label.setWrapText(true);
label.setPrefWidth(200);
label.setMaxWidth(180);
label.setTextAlignment(TextAlignment.RIGHT);
GridPane.setHalignment(label, HPos.RIGHT);
GridPane.setValignment(label, VPos.TOP);
FlowPane flowPane = new FlowPane();
flowPane.setPadding(new Insets(10, 10, 10, 10));

View File

@ -20,6 +20,7 @@ package io.bitsquare.gui.components.paymentmethods;
import com.google.common.base.Joiner;
import io.bitsquare.common.util.Tuple3;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.payment.PaymentAccount;
import io.bitsquare.payment.PaymentAccountContractData;
@ -47,8 +48,8 @@ public class SpecificBankForm extends BankForm {
}
public SpecificBankForm(PaymentAccount paymentAccount, InputValidator inputValidator,
GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.specificBanksAccountContractData = (SpecificBanksAccountContractData) paymentAccount.contractData;
}

View File

@ -18,6 +18,7 @@
package io.bitsquare.gui.components.paymentmethods;
import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.Layout;
import io.bitsquare.gui.util.validation.InputValidator;
import io.bitsquare.gui.util.validation.SwishValidator;
@ -48,8 +49,8 @@ public class SwishForm extends PaymentMethodForm {
return gridRow;
}
public SwishForm(PaymentAccount paymentAccount, SwishValidator swishValidator, InputValidator inputValidator, GridPane gridPane, int gridRow) {
super(paymentAccount, inputValidator, gridPane, gridRow);
public SwishForm(PaymentAccount paymentAccount, SwishValidator swishValidator, InputValidator inputValidator, GridPane gridPane, int gridRow, BSFormatter formatter) {
super(paymentAccount, inputValidator, gridPane, gridRow, formatter);
this.swishAccount = (SwishAccount) paymentAccount;
this.swishValidator = swishValidator;
}

View File

@ -24,6 +24,7 @@ import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.paymentmethods.BlockChainForm;
import io.bitsquare.gui.components.paymentmethods.PaymentMethodForm;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.FormBuilder;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.gui.util.Layout;
@ -59,6 +60,7 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
private final PerfectMoneyValidator perfectMoneyValidator;
private final SwishValidator swishValidator;
private final AltCoinAddressValidator altCoinAddressValidator;
private BSFormatter formatter;
private PaymentMethodForm paymentMethodForm;
private TitledGroupBg accountTitledGroupBg;
@ -76,7 +78,8 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
AliPayValidator aliPayValidator,
PerfectMoneyValidator perfectMoneyValidator,
SwishValidator swishValidator,
AltCoinAddressValidator altCoinAddressValidator) {
AltCoinAddressValidator altCoinAddressValidator,
BSFormatter formatter) {
super(model);
this.ibanValidator = ibanValidator;
@ -87,6 +90,7 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
this.perfectMoneyValidator = perfectMoneyValidator;
this.swishValidator = swishValidator;
this.altCoinAddressValidator = altCoinAddressValidator;
this.formatter = formatter;
}
@Override
@ -247,7 +251,7 @@ public class AltCoinAccountsView extends ActivatableViewAndModel<GridPane, AltCo
}
private PaymentMethodForm getPaymentMethodForm(PaymentAccount paymentAccount) {
return new BlockChainForm(paymentAccount, altCoinAddressValidator, inputValidator, root, gridRow);
return new BlockChainForm(paymentAccount, altCoinAddressValidator, inputValidator, root, gridRow, formatter);
}
private void removeNewAccountForm() {

View File

@ -23,6 +23,7 @@ import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.paymentmethods.*;
import io.bitsquare.gui.main.overlays.popups.Popup;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.gui.util.FormBuilder;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.gui.util.Layout;
@ -38,6 +39,7 @@ import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.text.TextAlignment;
import javafx.util.Callback;
import javafx.util.StringConverter;
@ -61,6 +63,7 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
private final PerfectMoneyValidator perfectMoneyValidator;
private final SwishValidator swishValidator;
private final AltCoinAddressValidator altCoinAddressValidator;
private BSFormatter formatter;
private PaymentMethodForm paymentMethodForm;
private TitledGroupBg accountTitledGroupBg;
@ -78,7 +81,8 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
AliPayValidator aliPayValidator,
PerfectMoneyValidator perfectMoneyValidator,
SwishValidator swishValidator,
AltCoinAddressValidator altCoinAddressValidator) {
AltCoinAddressValidator altCoinAddressValidator,
BSFormatter formatter) {
super(model);
this.ibanValidator = ibanValidator;
@ -89,6 +93,7 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
this.perfectMoneyValidator = perfectMoneyValidator;
this.swishValidator = swishValidator;
this.altCoinAddressValidator = altCoinAddressValidator;
this.formatter = formatter;
}
@Override
@ -156,8 +161,9 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
private void buildForm() {
addTitledGroupBg(root, gridRow, 2, "Manage accounts");
Tuple2<Label, ListView> tuple = addLabelListView(root, gridRow, "Your national currency accounts:", Layout.FIRST_ROW_DISTANCE);
Tuple2<Label, ListView> tuple = addLabelListView(root, gridRow, "Your national currency\naccounts:", Layout.FIRST_ROW_DISTANCE);
GridPane.setValignment(tuple.first, VPos.TOP);
tuple.first.setTextAlignment(TextAlignment.RIGHT);
paymentAccountsListView = tuple.second;
paymentAccountsListView.setPrefHeight(2 * Layout.LIST_ROW_HEIGHT + 14);
paymentAccountsListView.setCellFactory(new Callback<ListView<PaymentAccount>, ListCell<PaymentAccount>>() {
@ -274,21 +280,21 @@ public class FiatAccountsView extends ActivatableViewAndModel<GridPane, FiatAcco
private PaymentMethodForm getPaymentMethodForm(PaymentMethod paymentMethod, PaymentAccount paymentAccount) {
switch (paymentMethod.getId()) {
case PaymentMethod.OK_PAY_ID:
return new OKPayForm(paymentAccount, okPayValidator, inputValidator, root, gridRow);
return new OKPayForm(paymentAccount, okPayValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.PERFECT_MONEY_ID:
return new PerfectMoneyForm(paymentAccount, perfectMoneyValidator, inputValidator, root, gridRow);
return new PerfectMoneyForm(paymentAccount, perfectMoneyValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.SEPA_ID:
return new SepaForm(paymentAccount, ibanValidator, bicValidator, inputValidator, root, gridRow);
return new SepaForm(paymentAccount, ibanValidator, bicValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.NATIONAL_BANK_ID:
return new NationalBankForm(paymentAccount, inputValidator, root, gridRow);
return new NationalBankForm(paymentAccount, inputValidator, root, gridRow, formatter);
case PaymentMethod.SAME_BANK_ID:
return new SameBankForm(paymentAccount, inputValidator, root, gridRow);
return new SameBankForm(paymentAccount, inputValidator, root, gridRow, formatter);
case PaymentMethod.SPECIFIC_BANKS_ID:
return new SpecificBankForm(paymentAccount, inputValidator, root, gridRow);
return new SpecificBankForm(paymentAccount, inputValidator, root, gridRow, formatter);
case PaymentMethod.ALI_PAY_ID:
return new AliPayForm(paymentAccount, aliPayValidator, inputValidator, root, gridRow);
return new AliPayForm(paymentAccount, aliPayValidator, inputValidator, root, gridRow, formatter);
case PaymentMethod.SWISH_ID:
return new SwishForm(paymentAccount, swishValidator, inputValidator, root, gridRow);
return new SwishForm(paymentAccount, swishValidator, inputValidator, root, gridRow, formatter);
default:
log.error("Not supported PaymentMethod: " + paymentMethod);
return null;

View File

@ -101,7 +101,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
final ObservableList<PaymentAccount> paymentAccounts = FXCollections.observableArrayList();
private PaymentAccount paymentAccount;
PaymentAccount paymentAccount;
private boolean isTabSelected;
private Notification walletFundedNotification;

View File

@ -313,6 +313,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
void initWithData(Offer.Direction direction, TradeCurrency tradeCurrency) {
dataModel.initWithData(direction, tradeCurrency);
btcValidator.setPaymentMethod(dataModel.paymentAccount.getPaymentMethod());
}
@ -368,6 +369,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
}
public void onPaymentAccountSelected(PaymentAccount paymentAccount) {
btcValidator.setPaymentMethod(paymentAccount.getPaymentMethod());
dataModel.onPaymentAccountSelected(paymentAccount);
}

View File

@ -85,7 +85,7 @@ class OfferBookViewModel extends ActivatableViewModel {
// If id is empty string we ignore filter (display all methods)
private PaymentMethod selectedPaymentMethod = new PaymentMethod(SHOW_ALL_FLAG, 0, 0);
private PaymentMethod selectedPaymentMethod = new PaymentMethod(SHOW_ALL_FLAG, 0, 0, null);
private final ObservableList<OfferBookListItem> offerBookListItems;
private final ListChangeListener<OfferBookListItem> listChangeListener;
@ -334,19 +334,15 @@ class OfferBookViewModel extends ActivatableViewModel {
return false;
}
//TODO not tested with all combinations yet....
static boolean isPaymentAccountValidForOffer(Offer offer, PaymentAccount paymentAccount) {
// check if we have a matching currency
Set<String> paymentAccountCurrencyCodes = paymentAccount.getTradeCurrencies().stream().map(TradeCurrency::getCode).collect(Collectors.toSet());
boolean matchesCurrencyCode = paymentAccountCurrencyCodes.contains(offer.getCurrencyCode());
log.error("paymentAccount.paymentAccountCurrencyCodes " + paymentAccountCurrencyCodes);
log.error("offer.getCurrencyCode() " + offer.getCurrencyCode());
log.error("matchesCurrencyCode " + matchesCurrencyCode);
if (!matchesCurrencyCode)
return false;
// check if we have a matching payment method or if its a bank account payment method which is treated special
if (paymentAccount instanceof CountryBasedPaymentAccount) {
CountryBasedPaymentAccount countryBasedPaymentAccount = (CountryBasedPaymentAccount) paymentAccount;
@ -358,15 +354,11 @@ class OfferBookViewModel extends ActivatableViewModel {
// check if we have a matching country
boolean matchesCountryCodes = offer.getAcceptedCountryCodes().contains(countryBasedPaymentAccount.getCountry().code);
log.error("offer.getAcceptedCountryCodes() " + offer.getAcceptedCountryCodes());
log.error("paymentAccount.getCountry().code " + countryBasedPaymentAccount.getCountry().code);
log.error("matchesCountryCodes " + matchesCountryCodes);
if (!matchesCountryCodes)
return false;
if (paymentAccount instanceof SepaAccount || offer.getPaymentMethod().equals(PaymentMethod.SEPA)) {
boolean samePaymentMethod = paymentAccount.getPaymentMethod().equals(offer.getPaymentMethod());
log.error("samePaymentMethod " + samePaymentMethod);
return samePaymentMethod;
} else if (offer.getPaymentMethod().equals(PaymentMethod.SAME_BANK) ||
offer.getPaymentMethod().equals(PaymentMethod.SPECIFIC_BANKS)) {
@ -376,36 +368,20 @@ class OfferBookViewModel extends ActivatableViewModel {
// check if we have a matching bank
boolean offerSideMatchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
log.error("offer.getAcceptedBankIds() " + offer.getAcceptedBankIds());
log.error("((BankAccount) paymentAccount).getBankId() " + ((BankAccount) paymentAccount).getBankId());
log.error("offerSideMatchesBank " + offerSideMatchesBank);
log.error("paymentAccountSideMatchesBank " + paymentAccountSideMatchesBank);
return offerSideMatchesBank && paymentAccountSideMatchesBank;
} else {
// national or same bank
boolean matchesBank = offer.getAcceptedBankIds().contains(((BankAccount) paymentAccount).getBankId());
log.error("offer.getAcceptedBankIds() " + offer.getAcceptedBankIds());
log.error("((BankAccount) paymentAccount).getBankId() " + ((BankAccount) paymentAccount).getBankId());
log.error("matchesBank " + matchesBank);
return matchesBank;
}
} else {
if (paymentAccount instanceof SpecificBanksAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SpecificBanksAccount) paymentAccount).getAcceptedBanks().contains(offer.getBankId());
log.error("offer.getAcceptedBankIds() " + offer.getAcceptedBankIds());
log.error("((BankAccount) paymentAccount).getBankId() " + ((BankAccount) paymentAccount).getBankId());
log.error("paymentAccountSideMatchesBank " + paymentAccountSideMatchesBank);
return paymentAccountSideMatchesBank;
} else if (paymentAccount instanceof SameBankAccount) {
// check if we have a matching bank
boolean paymentAccountSideMatchesBank = ((SameBankAccount) paymentAccount).getBankId().equals(offer.getBankId());
log.error("offer.getAcceptedBankIds() " + offer.getAcceptedBankIds());
log.error("((BankAccount) paymentAccount).getBankId() " + ((BankAccount) paymentAccount).getBankId());
log.error("paymentAccountSideMatchesBank " + paymentAccountSideMatchesBank);
return paymentAccountSideMatchesBank;
} else {
// national

View File

@ -88,7 +88,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
final ObjectProperty<Coin> feeFromFundingTxProperty = new SimpleObjectProperty(Coin.NEGATIVE_SATOSHI);
private BalanceListener balanceListener;
private PaymentAccount paymentAccount;
PaymentAccount paymentAccount;
private boolean isTabSelected;

View File

@ -170,6 +170,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
};
offer.errorMessageProperty().addListener(offerErrorListener);
errorMessage.set(offer.errorMessageProperty().get());
btcValidator.setPaymentMethod(dataModel.paymentAccount.getPaymentMethod());
}
@ -195,6 +197,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
public void onPaymentAccountSelected(PaymentAccount paymentAccount) {
dataModel.onPaymentAccountSelected(paymentAccount);
btcValidator.setPaymentMethod(paymentAccount.getPaymentMethod());
}
public void onShowPayFundsScreen() {

View File

@ -17,9 +17,11 @@
package io.bitsquare.gui.util.validation;
import io.bitsquare.btc.Restrictions;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.BSResources;
import io.bitsquare.payment.PaymentMethod;
import org.bitcoinj.core.Coin;
import org.jetbrains.annotations.NotNull;
import javax.inject.Inject;
import java.math.BigDecimal;
@ -28,11 +30,18 @@ public class BtcValidator extends NumberValidator {
private final BSFormatter formatter;
@NotNull
private PaymentMethod paymentMethod;
@Inject
public BtcValidator(BSFormatter formatter) {
this.formatter = formatter;
}
public void setPaymentMethod(@NotNull PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}
@Override
public ValidationResult validate(String input) {
ValidationResult result = validateIfNotEmpty(input);
@ -61,10 +70,8 @@ public class BtcValidator extends NumberValidator {
}
protected ValidationResult validateIfNotExceedsMaxBtcValue(String input) {
BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.longValue() > Restrictions.MAX_TRADE_AMOUNT.longValue())
return new ValidationResult(false, BSResources.get("validation.btc.toLarge", formatter.formatCoinWithCode(Restrictions.MAX_TRADE_AMOUNT)));
if (Coin.parseCoin(input).compareTo(paymentMethod.getMaxTradeLimitInBitcoin()) > 0)
return new ValidationResult(false, BSResources.get("validation.btc.toLarge", formatter.formatCoinWithCode(paymentMethod.getMaxTradeLimitInBitcoin())));
else
return new ValidationResult(true);
}

View File

@ -17,7 +17,6 @@
package io.bitsquare.gui.util.validation;
import io.bitsquare.btc.Restrictions;
import io.bitsquare.gui.util.BSFormatter;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
@ -38,7 +37,6 @@ public class BtcValidatorTest {
assertTrue(validator.validate(".1").isValid);
assertTrue(validator.validate("0.12345678").isValid);
assertTrue(validator.validate(Coin.SATOSHI.toPlainString()).isValid);
assertTrue(validator.validate(Restrictions.MAX_TRADE_AMOUNT.toPlainString()).isValid);
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("").isValid);
@ -50,8 +48,6 @@ public class BtcValidatorTest {
assertFalse(validator.validate("0.000,1").isValid);
assertFalse(validator.validate("0.123456789").isValid);
assertFalse(validator.validate("-1").isValid);
assertFalse(validator.validate(String.valueOf(Restrictions.MAX_TRADE_AMOUNT.longValue() + Coin.SATOSHI
.longValue())).isValid);
assertFalse(validator.validate(NetworkParameters.MAX_MONEY.toPlainString()).isValid);
}