Search in sources :

Example 61 with Coin

use of org.bitcoinj.core.Coin in project bisq-api by mrosseel.

the class BisqProxy method offerMake.

public CompletableFuture<Offer> offerMake(boolean fundUsingBisqWallet, String offerId, String accountId, OfferPayload.Direction direction, BigDecimal amount, BigDecimal minAmount, boolean useMarketBasedPrice, Double marketPriceMargin, String marketPair, long fiatPrice, Long buyerSecurityDeposit) {
    // exception from gui code is not clear enough, so this check is added. Missing money is another possible check but that's clear in the gui exception.
    final CompletableFuture<Offer> futureResult = new CompletableFuture<>();
    if (!fundUsingBisqWallet && null == offerId)
        return failFuture(futureResult, new ValidationException("Specify offerId of earlier prepared offer if you want to use dedicated wallet address."));
    final OfferBuilder offerBuilder = injector.getInstance(OfferBuilder.class);
    final Offer offer;
    try {
        offer = offerBuilder.build(offerId, accountId, direction, amount, minAmount, useMarketBasedPrice, marketPriceMargin, marketPair, fiatPrice, buyerSecurityDeposit);
    } catch (Exception e) {
        return failFuture(futureResult, e);
    }
    Coin reservedFundsForOffer = OfferUtil.isBuyOffer(direction) ? preferences.getBuyerSecurityDepositAsCoin() : Restrictions.getSellerSecurityDeposit();
    if (!OfferUtil.isBuyOffer(direction))
        reservedFundsForOffer = reservedFundsForOffer.add(Coin.valueOf(amount.longValue()));
    // TODO check if there is sufficient money cause openOfferManager will log exception and pass just message
    // TODO openOfferManager should return CompletableFuture or at least send full exception to error handler
    openOfferManager.placeOffer(offer, reservedFundsForOffer, fundUsingBisqWallet, transaction -> futureResult.complete(offer), error -> {
        if (error.contains("Insufficient money")) {
            futureResult.completeExceptionally(new InsufficientMoneyException(error));
        } else
            futureResult.completeExceptionally(new RuntimeException(error));
    });
    return futureResult;
}
Also used : Coin(org.bitcoinj.core.Coin) CompletableFuture(java.util.concurrent.CompletableFuture) ValidationException(javax.validation.ValidationException) PaymentAccountUtil.isPaymentAccountValidForOffer(io.bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer) ValidationException(javax.validation.ValidationException)

Example 62 with Coin

use of org.bitcoinj.core.Coin in project bisq-api by mrosseel.

the class OfferBuilder method getMakerFee.

@Nullable
private Coin getMakerFee(boolean isCurrencyForMakerFeeBtc, Coin amount, double marketPriceMargin) {
    if (amount != null) {
        final Coin feePerBtc = CoinUtil.getFeePerBtc(FeeService.getMakerFeePerBtc(isCurrencyForMakerFeeBtc), amount);
        double makerFeeAsDouble = (double) feePerBtc.value;
        if (marketPriceAvailable) {
            if (marketPriceMargin > 0)
                makerFeeAsDouble = makerFeeAsDouble * Math.sqrt(marketPriceMargin * 100);
            else
                makerFeeAsDouble = 0;
            // For BTC we round so min value change is 100 satoshi
            if (isCurrencyForMakerFeeBtc)
                makerFeeAsDouble = MathUtils.roundDouble(makerFeeAsDouble / 100, 0) * 100;
        }
        return CoinUtil.maxCoin(Coin.valueOf(MathUtils.doubleToLong(makerFeeAsDouble)), FeeService.getMinMakerFee(isCurrencyForMakerFeeBtc));
    } else {
        return null;
    }
}
Also used : Coin(org.bitcoinj.core.Coin) Nullable(javax.annotation.Nullable)

Example 63 with Coin

use of org.bitcoinj.core.Coin in project bisq-api by mrosseel.

the class OfferBuilder method build.

public Offer build(String offerId, String accountId, OfferPayload.Direction direction, BigDecimal amount, BigDecimal minAmount, boolean useMarketBasedPrice, Double marketPriceMargin, String marketPair, long fiatPrice, Long buyerSecurityDeposit) throws NoAcceptedArbitratorException, PaymentAccountNotFoundException, IncompatiblePaymentAccountException {
    final List<NodeAddress> acceptedArbitratorAddresses = user.getAcceptedArbitratorAddresses();
    if (null == acceptedArbitratorAddresses || acceptedArbitratorAddresses.size() == 0) {
        throw new NoAcceptedArbitratorException("No arbitrator has been chosen");
    }
    // Checked that if fixed we have a fixed price, if percentage we have a percentage
    if (marketPriceMargin == null && useMarketBasedPrice) {
        throw new ValidationException("When choosing PERCENTAGE price, fill in percentageFromMarketPrice");
    } else if (0 == fiatPrice && !useMarketBasedPrice) {
        throw new ValidationException("When choosing FIXED price, fill in fixed_price with a price > 0");
    }
    // fix marketPair if it's lowercase
    marketPair = marketPair.toUpperCase();
    checkMarketValidity(marketPair);
    Market market = new Market(marketPair);
    // if right side is fiat, then left is base currency.
    // else right side is base currency.
    String baseCurrencyCode = CurrencyUtil.isFiatCurrency(market.getRsymbol()) ? market.getLsymbol() : market.getRsymbol();
    String counterCurrencyCode = CurrencyUtil.isFiatCurrency(market.getRsymbol()) ? market.getRsymbol() : market.getLsymbol();
    Optional<PaymentAccount> optionalAccount = getPaymentAccounts().stream().filter(account1 -> account1.getId().equals(accountId)).findFirst();
    if (!optionalAccount.isPresent()) {
        throw new PaymentAccountNotFoundException("Could not find payment account with id: " + accountId);
    }
    PaymentAccount paymentAccount = optionalAccount.get();
    // COPIED from CreateDataOfferModel: TODO refactor uit of GUI module  /////////////////////////////
    String countryCode = paymentAccount instanceof CountryBasedPaymentAccount ? ((CountryBasedPaymentAccount) paymentAccount).getCountry().code : null;
    ArrayList<String> acceptedCountryCodes = null;
    if (paymentAccount instanceof SepaAccount) {
        acceptedCountryCodes = new ArrayList<>();
        acceptedCountryCodes.addAll(((SepaAccount) paymentAccount).getAcceptedCountryCodes());
    } else if (paymentAccount instanceof CountryBasedPaymentAccount) {
        acceptedCountryCodes = new ArrayList<>();
        acceptedCountryCodes.add(((CountryBasedPaymentAccount) paymentAccount).getCountry().code);
    }
    String bankId = paymentAccount instanceof BankAccount ? ((BankAccount) paymentAccount).getBankId() : null;
    ArrayList<String> acceptedBanks = null;
    if (paymentAccount instanceof SpecificBanksAccount) {
        acceptedBanks = new ArrayList<>(((SpecificBanksAccount) paymentAccount).getAcceptedBanks());
    } else if (paymentAccount instanceof SameBankAccount) {
        acceptedBanks = new ArrayList<>();
        acceptedBanks.add(((SameBankAccount) paymentAccount).getBankId());
    }
    long maxTradeLimit = paymentAccount.getPaymentMethod().getMaxTradeLimitAsCoin(baseCurrencyCode).value;
    long maxTradePeriod = paymentAccount.getPaymentMethod().getMaxTradePeriod();
    boolean isPrivateOffer = false;
    boolean useAutoClose = false;
    boolean useReOpenAfterAutoClose = false;
    long lowerClosePrice = 0;
    long upperClosePrice = 0;
    String hashOfChallenge = null;
    HashMap<String, String> extraDataMap = null;
    // COPIED from CreateDataOfferModel /////////////////////////////
    updateMarketPriceAvailable(baseCurrencyCode);
    // TODO dummy values in this constructor !!!
    Coin coinAmount = Coin.valueOf(amount.longValueExact());
    if (null == buyerSecurityDeposit) {
        buyerSecurityDeposit = preferences.getBuyerSecurityDepositAsCoin().value;
    }
    OfferPayload offerPayload = new OfferPayload(null == offerId ? UUID.randomUUID().toString() : offerId, new Date().getTime(), p2PService.getAddress(), keyRing.getPubKeyRing(), direction, fiatPrice, marketPriceMargin, useMarketBasedPrice, amount.longValueExact(), minAmount.longValueExact(), baseCurrencyCode, counterCurrencyCode, acceptedArbitratorAddresses, user.getAcceptedMediatorAddresses(), paymentAccount.getPaymentMethod().getId(), paymentAccount.getId(), // will be filled in by BroadcastMakerFeeTx class
    null, countryCode, acceptedCountryCodes, bankId, acceptedBanks, Version.VERSION, btcWalletService.getLastBlockSeenHeight(), // default also used in code CreateOfferDataModel
    feeService.getTxFee(600).value, getMakerFee(coinAmount, marketPriceMargin).value, preferences.getPayFeeInBtc() || !isBsqForFeeAvailable(coinAmount, marketPriceMargin), buyerSecurityDeposit, Restrictions.getSellerSecurityDeposit().value, maxTradeLimit, maxTradePeriod, useAutoClose, useReOpenAfterAutoClose, upperClosePrice, lowerClosePrice, isPrivateOffer, hashOfChallenge, extraDataMap, Version.TRADE_PROTOCOL_VERSION);
    Offer offer = new Offer(offerPayload);
    offer.setPriceFeedService(priceFeedService);
    if (!isPaymentAccountValidForOffer(offer, paymentAccount)) {
        final String errorMessage = "PaymentAccount is not valid for offer, needs " + offer.getCurrencyCode();
        throw new IncompatiblePaymentAccountException(errorMessage);
    }
    if (null == getMakerFee(false, Coin.valueOf(amount.longValue()), marketPriceMargin)) {
        throw new ValidationException("makerFee must not be null");
    }
    return offer;
}
Also used : java.util(java.util) Version(io.bisq.common.app.Version) Coin(org.bitcoinj.core.Coin) Inject(com.google.inject.Inject) Preferences(io.bisq.core.user.Preferences) User(io.bisq.core.user.User) StringUtils(org.apache.commons.lang3.StringUtils) PaymentAccountUtil.isPaymentAccountValidForOffer(io.bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer) BigDecimal(java.math.BigDecimal) CoinUtil(io.bisq.core.util.CoinUtil) Market(io.bisq.api.model.Market) FeeService(io.bisq.core.provider.fee.FeeService) CurrencyUtil(io.bisq.common.locale.CurrencyUtil) Nullable(javax.annotation.Nullable) OfferPayload(io.bisq.core.offer.OfferPayload) BisqEnvironment(io.bisq.core.app.BisqEnvironment) NodeAddress(io.bisq.network.p2p.NodeAddress) BsqWalletService(io.bisq.core.btc.wallet.BsqWalletService) MathUtils(io.bisq.common.util.MathUtils) Offer(io.bisq.core.offer.Offer) io.bisq.core.payment(io.bisq.core.payment) BtcWalletService(io.bisq.core.btc.wallet.BtcWalletService) P2PService(io.bisq.network.p2p.P2PService) ValidationException(javax.validation.ValidationException) KeyRing(io.bisq.common.crypto.KeyRing) PriceFeedService(io.bisq.core.provider.price.PriceFeedService) Restrictions(io.bisq.core.btc.Restrictions) ValidationException(javax.validation.ValidationException) Coin(org.bitcoinj.core.Coin) NodeAddress(io.bisq.network.p2p.NodeAddress) Market(io.bisq.api.model.Market) PaymentAccountUtil.isPaymentAccountValidForOffer(io.bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer) Offer(io.bisq.core.offer.Offer) OfferPayload(io.bisq.core.offer.OfferPayload)

Example 64 with Coin

use of org.bitcoinj.core.Coin in project bisq-api by mrosseel.

the class MainViewModelHeadless method updateAvailableBalance.

private void updateAvailableBalance() {
    Coin totalAvailableBalance = Coin.valueOf(tradeManager.getAddressEntriesForAvailableBalanceStream().mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).getValue()).sum());
    String value = formatter.formatCoinWithCode(totalAvailableBalance);
    // If we get full precision the BTC postfix breaks layout so we omit it
    if (value.length() > 11)
        value = formatter.formatCoin(totalAvailableBalance);
    availableBalance.set(value);
}
Also used : Coin(org.bitcoinj.core.Coin)

Aggregations

Coin (org.bitcoinj.core.Coin)64 Transaction (org.bitcoinj.core.Transaction)16 AddressEntry (io.bitsquare.btc.AddressEntry)13 WalletService (io.bitsquare.btc.WalletService)13 Address (org.bitcoinj.core.Address)10 Popup (io.bitsquare.gui.main.overlays.popups.Popup)8 Inject (com.google.inject.Inject)7 Nullable (javax.annotation.Nullable)7 BalanceListener (io.bitsquare.btc.listeners.BalanceListener)6 Collectors (java.util.stream.Collectors)6 FXCollections (javafx.collections.FXCollections)6 ListChangeListener (javafx.collections.ListChangeListener)6 ObservableList (javafx.collections.ObservableList)6 BSFormatter (io.bitsquare.gui.util.BSFormatter)5 Offer (io.bitsquare.trade.offer.Offer)5 AddressEntry (io.bisq.core.btc.AddressEntry)4 Trade (io.bisq.core.trade.Trade)4 UserThread (io.bitsquare.common.UserThread)4 PaymentAccountUtil.isPaymentAccountValidForOffer (io.bisq.core.payment.PaymentAccountUtil.isPaymentAccountValidForOffer)3 DevFlags (io.bitsquare.app.DevFlags)3