Search in sources :

Example 6 with PaymentAccount

use of bisq.core.payment.PaymentAccount in project bisq-desktop by bisq-network.

the class TakeOfferDataModel method initWithData.

// /////////////////////////////////////////////////////////////////////////////////////////
// API
// /////////////////////////////////////////////////////////////////////////////////////////
// called before activate
void initWithData(Offer offer) {
    this.offer = offer;
    tradePrice = offer.getPrice();
    addressEntry = btcWalletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.OFFER_FUNDING);
    checkNotNull(addressEntry, "addressEntry must not be null");
    ObservableList<PaymentAccount> possiblePaymentAccounts = getPossiblePaymentAccounts();
    checkArgument(!possiblePaymentAccounts.isEmpty(), "possiblePaymentAccounts.isEmpty()");
    paymentAccount = possiblePaymentAccounts.get(0);
    long myLimit = accountAgeWitnessService.getMyTradeLimit(paymentAccount, getCurrencyCode());
    this.amount.set(Coin.valueOf(Math.min(offer.getAmount().value, myLimit)));
    securityDeposit = offer.getDirection() == OfferPayload.Direction.SELL ? getBuyerSecurityDeposit() : getSellerSecurityDeposit();
    // Taker pays 3 times the tx fee (taker fee, deposit, payout) because the mining fee might be different when maker created the offer
    // and reserved his funds. Taker creates at least taker fee and deposit tx at nearly the same moment. Just the payout will
    // be later and still could lead to issues if the required fee changed a lot in the meantime. using RBF and/or
    // multiple batch-signed payout tx with different fees might be an option but RBF is not supported yet in BitcoinJ
    // and batched txs would add more complexity to the trade protocol.
    // A typical trade fee tx has about 260 bytes (if one input). The trade txs has about 336-414 bytes.
    // We use 320 as a average value.
    // trade fee tx: 260 bytes (1 input)
    // deposit tx: 336 bytes (1 MS output+ OP_RETURN) - 414 bytes (1 MS output + OP_RETURN + change in case of smaller trade amount)
    // payout tx: 371 bytes
    // disputed payout tx: 408 bytes
    // Set the default values (in rare cases if the fee request was not done yet we get the hard coded default values)
    // But the "take offer" happens usually after that so we should have already the value from the estimation service.
    txFeePerByteFromFeeService = feeService.getTxFeePerByte();
    txFeeFromFeeService = getTxFeeBySize(feeTxSize);
    // We request to get the actual estimated fee
    log.info("Start requestTxFee: txFeeFromFeeService={}", txFeeFromFeeService);
    feeService.requestFees(() -> {
        if (!freezeFee) {
            txFeePerByteFromFeeService = feeService.getTxFeePerByte();
            txFeeFromFeeService = getTxFeeBySize(feeTxSize);
            calculateTotalToPay();
            log.info("Completed requestTxFee: txFeeFromFeeService={}", txFeeFromFeeService);
        } else {
            log.warn("We received the tx fee respnse after we have shown the funding screen and ignore that " + "to avoid that the total funds to pay changes due cahnged tx fees.");
        }
    }, null);
    calculateVolume();
    calculateTotalToPay();
    balanceListener = new BalanceListener(addressEntry.getAddress()) {

        @Override
        public void onBalanceChanged(Coin balance, Transaction tx) {
            updateBalance();
        /*if (isMainNet.get()) {
                    SettableFuture<Coin> future = blockchainService.requestFee(tx.getHashAsString());
                    Futures.addCallback(future, new FutureCallback<Coin>() {
                        public void onSuccess(Coin fee) {
                            UserThread.execute(() -> setFeeFromFundingTx(fee));
                        }

                        public void onFailure(@NotNull Throwable throwable) {
                            UserThread.execute(() -> new Popup<>()
                                    .warning("We did not get a response for the request of the mining fee used " +
                                            "in the funding transaction.\n\n" +
                                            "Are you sure you used a sufficiently high fee of at least " +
                                            formatter.formatCoinWithCode(FeePolicy.getMinRequiredFeeForFundingTx()) + "?")
                                    .actionButtonText("Yes, I used a sufficiently high fee.")
                                    .onAction(() -> setFeeFromFundingTx(FeePolicy.getMinRequiredFeeForFundingTx()))
                                    .closeButtonText("No. Let's cancel that payment.")
                                    .onClose(() -> setFeeFromFundingTx(Coin.NEGATIVE_SATOSHI))
                                    .show());
                        }
                    });
                } else {
                    setFeeFromFundingTx(FeePolicy.getMinRequiredFeeForFundingTx());
                    isFeeFromFundingTxSufficient.set(feeFromFundingTx.compareTo(FeePolicy.getMinRequiredFeeForFundingTx()) >= 0);
                }*/
        }
    };
    offer.resetState();
    priceFeedService.setCurrencyCode(offer.getCurrencyCode());
}
Also used : Coin(org.bitcoinj.core.Coin) BalanceListener(bisq.core.btc.listeners.BalanceListener) Transaction(org.bitcoinj.core.Transaction) PaymentAccount(bisq.core.payment.PaymentAccount)

Example 7 with PaymentAccount

use of bisq.core.payment.PaymentAccount in project bisq-desktop by bisq-network.

the class CreateOfferDataModel method initWithData.

// /////////////////////////////////////////////////////////////////////////////////////////
// API
// /////////////////////////////////////////////////////////////////////////////////////////
// called before activate()
boolean initWithData(OfferPayload.Direction direction, TradeCurrency tradeCurrency) {
    this.direction = direction;
    this.tradeCurrency = tradeCurrency;
    fillPaymentAccounts();
    PaymentAccount account;
    PaymentAccount lastSelectedPaymentAccount = preferences.getSelectedPaymentAccountForCreateOffer();
    if (lastSelectedPaymentAccount != null && user.getPaymentAccounts() != null && user.getPaymentAccounts().contains(lastSelectedPaymentAccount)) {
        account = lastSelectedPaymentAccount;
    } else {
        account = user.findFirstPaymentAccountWithCurrency(tradeCurrency);
    }
    if (account != null) {
        this.paymentAccount = account;
    } else {
        Optional<PaymentAccount> paymentAccountOptional = paymentAccounts.stream().findAny();
        if (paymentAccountOptional.isPresent()) {
            this.paymentAccount = paymentAccountOptional.get();
        } else {
            log.warn("PaymentAccount not available. Should never get called as in offer view you should not be able to open a create offer view");
            return false;
        }
    }
    setTradeCurrencyFromPaymentAccount(paymentAccount);
    tradeCurrencyCode.set(this.tradeCurrency.getCode());
    priceFeedService.setCurrencyCode(tradeCurrencyCode.get());
    // We request to get the actual estimated fee
    requestTxFee();
    // Set the default values (in rare cases if the fee request was not done yet we get the hard coded default values)
    // But offer creation happens usually after that so we should have already the value from the estimation service.
    txFeeFromFeeService = feeService.getTxFee(feeTxSize);
    calculateVolume();
    calculateTotalToPay();
    updateBalance();
    return true;
}
Also used : CountryBasedPaymentAccount(bisq.core.payment.CountryBasedPaymentAccount) PaymentAccount(bisq.core.payment.PaymentAccount)

Example 8 with PaymentAccount

use of bisq.core.payment.PaymentAccount in project bisq-desktop by bisq-network.

the class CreateOfferView method onPaymentAccountsComboBoxSelected.

private void onPaymentAccountsComboBoxSelected() {
    // Temporary deactivate handler as the payment account change can populate a new currency list and causes
    // unwanted selection events (item 0)
    currencyComboBox.setOnAction(null);
    PaymentAccount paymentAccount = paymentAccountsComboBox.getSelectionModel().getSelectedItem();
    if (paymentAccount != null) {
        maybeShowClearXchangeWarning(paymentAccount);
        currencyComboBox.setVisible(paymentAccount.hasMultipleCurrencies());
        if (paymentAccount.hasMultipleCurrencies()) {
            final List<TradeCurrency> tradeCurrencies = paymentAccount.getTradeCurrencies();
            currencyComboBox.setItems(FXCollections.observableArrayList(tradeCurrencies));
            if (paymentAccount.getSelectedTradeCurrency() != null)
                currencyComboBox.getSelectionModel().select(paymentAccount.getSelectedTradeCurrency());
            else if (tradeCurrencies.contains(model.getTradeCurrency()))
                currencyComboBox.getSelectionModel().select(model.getTradeCurrency());
            else
                currencyComboBox.getSelectionModel().select(tradeCurrencies.get(0));
            model.onPaymentAccountSelected(paymentAccount);
        } else {
            TradeCurrency singleTradeCurrency = paymentAccount.getSingleTradeCurrency();
            if (singleTradeCurrency != null)
                currencyTextField.setText(singleTradeCurrency.getNameAndCode());
            model.onPaymentAccountSelected(paymentAccount);
            model.onCurrencySelected(model.dataModel.getTradeCurrency());
        }
    } else {
        currencyComboBox.setVisible(false);
        currencyTextField.setText("");
    }
    currencyComboBox.setOnAction(currencyComboBoxSelectionHandler);
}
Also used : TradeCurrency(bisq.core.locale.TradeCurrency) PaymentAccount(bisq.core.payment.PaymentAccount)

Example 9 with PaymentAccount

use of bisq.core.payment.PaymentAccount in project bisq-desktop by bisq-network.

the class CreateOfferViewModelTest method setUp.

@Before
public void setUp() {
    final CryptoCurrency btc = new CryptoCurrency("BTC", "bitcoin");
    GlobalSettings.setDefaultTradeCurrency(btc);
    Res.setBaseCurrencyCode(btc.getCode());
    Res.setBaseCurrencyName(btc.getName());
    final BSFormatter bsFormatter = new BSFormatter();
    final BtcValidator btcValidator = new BtcValidator(bsFormatter);
    final AltcoinValidator altcoinValidator = new AltcoinValidator();
    final FiatPriceValidator fiatPriceValidator = new FiatPriceValidator();
    FeeService feeService = mock(FeeService.class);
    AddressEntry addressEntry = mock(AddressEntry.class);
    BtcWalletService btcWalletService = mock(BtcWalletService.class);
    PriceFeedService priceFeedService = mock(PriceFeedService.class);
    User user = mock(User.class);
    PaymentAccount paymentAccount = mock(PaymentAccount.class);
    BsqWalletService bsqWalletService = mock(BsqWalletService.class);
    SecurityDepositValidator securityDepositValidator = mock(SecurityDepositValidator.class);
    when(btcWalletService.getOrCreateAddressEntry(anyString(), any())).thenReturn(addressEntry);
    when(btcWalletService.getBalanceForAddress(any())).thenReturn(Coin.valueOf(1000L));
    when(priceFeedService.updateCounterProperty()).thenReturn(new SimpleIntegerProperty());
    when(priceFeedService.getMarketPrice(anyString())).thenReturn(new MarketPrice("USD", 12684.0450, Instant.now().getEpochSecond(), true));
    when(feeService.getTxFee(anyInt())).thenReturn(Coin.valueOf(1000L));
    when(user.findFirstPaymentAccountWithCurrency(any())).thenReturn(paymentAccount);
    when(user.getPaymentAccountsAsObservable()).thenReturn(FXCollections.observableSet());
    when(securityDepositValidator.validate(any())).thenReturn(new InputValidator.ValidationResult(false));
    CreateOfferDataModel dataModel = new CreateOfferDataModel(null, btcWalletService, bsqWalletService, empty, user, null, null, priceFeedService, null, null, null, feeService, bsFormatter);
    dataModel.initWithData(OfferPayload.Direction.BUY, new CryptoCurrency("BTC", "bitcoin"));
    dataModel.activate();
    model = new CreateOfferViewModel(dataModel, null, fiatPriceValidator, altcoinValidator, btcValidator, null, securityDepositValidator, null, null, priceFeedService, null, null, bsFormatter, null);
    model.activate();
}
Also used : BtcValidator(bisq.desktop.util.validation.BtcValidator) FiatPriceValidator(bisq.desktop.util.validation.FiatPriceValidator) User(bisq.core.user.User) AddressEntry(bisq.core.btc.AddressEntry) PaymentAccount(bisq.core.payment.PaymentAccount) FeeService(bisq.core.provider.fee.FeeService) BSFormatter(bisq.desktop.util.BSFormatter) AltcoinValidator(bisq.desktop.util.validation.AltcoinValidator) CryptoCurrency(bisq.core.locale.CryptoCurrency) SecurityDepositValidator(bisq.desktop.util.validation.SecurityDepositValidator) MarketPrice(bisq.core.provider.price.MarketPrice) InputValidator(bisq.core.util.validation.InputValidator) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) PriceFeedService(bisq.core.provider.price.PriceFeedService) BsqWalletService(bisq.core.btc.wallet.BsqWalletService) SimpleIntegerProperty(javafx.beans.property.SimpleIntegerProperty) Before(org.junit.Before)

Example 10 with PaymentAccount

use of bisq.core.payment.PaymentAccount in project bisq-desktop by bisq-network.

the class OfferBookViewModelTest method getCryptoAccount.

private PaymentAccount getCryptoAccount(String currencyCode) {
    PaymentAccount paymentAccount = new CryptoCurrencyAccount();
    paymentAccount.addCurrency(new CryptoCurrency(currencyCode, null));
    return paymentAccount;
}
Also used : CryptoCurrency(bisq.core.locale.CryptoCurrency) CountryBasedPaymentAccount(bisq.core.payment.CountryBasedPaymentAccount) PaymentAccount(bisq.core.payment.PaymentAccount) CryptoCurrencyAccount(bisq.core.payment.CryptoCurrencyAccount)

Aggregations

PaymentAccount (bisq.core.payment.PaymentAccount)17 CryptoCurrency (bisq.core.locale.CryptoCurrency)7 TradeCurrency (bisq.core.locale.TradeCurrency)7 PaymentMethod (bisq.core.payment.payload.PaymentMethod)7 AccountAgeWitnessService (bisq.core.payment.AccountAgeWitnessService)6 Res (bisq.core.locale.Res)5 User (bisq.core.user.User)5 BSFormatter (bisq.desktop.util.BSFormatter)5 UserThread (bisq.common.UserThread)4 Tuple3 (bisq.common.util.Tuple3)4 CryptoCurrencyAccount (bisq.core.payment.CryptoCurrencyAccount)4 InputValidator (bisq.core.util.validation.InputValidator)4 Popup (bisq.desktop.main.overlays.popups.Popup)4 Tuple2 (bisq.common.util.Tuple2)3 FiatCurrency (bisq.core.locale.FiatCurrency)3 CountryBasedPaymentAccount (bisq.core.payment.CountryBasedPaymentAccount)3 PaymentAccountFactory (bisq.core.payment.PaymentAccountFactory)3 ActivatableViewAndModel (bisq.desktop.common.view.ActivatableViewAndModel)3 FxmlView (bisq.desktop.common.view.FxmlView)3 AutoTooltipButton (bisq.desktop.components.AutoTooltipButton)3