use of io.bisq.core.offer.Offer 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;
}
use of io.bisq.core.offer.Offer in project bisq-api by mrosseel.
the class OfferResource method takeOffer.
@ApiOperation(value = "Take offer", response = TradeDetails.class)
@POST
@Path("/{id}/take")
public void takeOffer(@Suspended final AsyncResponse asyncResponse, @PathParam("id") String id, @Valid TakeOffer data) {
// TODO how do we go about not blocking this REST thread?
final CompletableFuture<Trade> completableFuture = bisqProxy.offerTake(id, data.paymentAccountId, data.amount, true);
completableFuture.thenApply(trade -> asyncResponse.resume(new TradeDetails(trade))).exceptionally(e -> {
final Throwable cause = e.getCause();
final Response.ResponseBuilder responseBuilder;
if (cause instanceof ValidationException) {
final int status = 422;
responseBuilder = toValidationErrorResponse(cause, status);
} else if (cause instanceof IncompatiblePaymentAccountException) {
responseBuilder = toValidationErrorResponse(cause, 423);
} else if (cause instanceof NoAcceptedArbitratorException) {
responseBuilder = toValidationErrorResponse(cause, 424);
} else if (cause instanceof PaymentAccountNotFoundException) {
responseBuilder = toValidationErrorResponse(cause, 425);
} else if (cause instanceof InsufficientMoneyException) {
responseBuilder = toValidationErrorResponse(cause, 427);
} else if (cause instanceof NotFoundException) {
responseBuilder = toValidationErrorResponse(cause, 404);
} else {
final String message = cause.getMessage();
responseBuilder = Response.status(500);
if (null != message)
responseBuilder.entity(new ValidationErrorMessage(ImmutableList.of(message)));
log.error("Unable to take offer: " + id + " " + Json.pretty(data), cause);
}
return asyncResponse.resume(responseBuilder.build());
});
}
Aggregations