offer_take is code complete but needs to be tested further.

This commit is contained in:
Mike Rosseel 2017-07-27 18:44:02 +02:00
parent 3f4c607b33
commit 79d6fe22a4
3 changed files with 146 additions and 38 deletions

View file

@ -1,6 +1,8 @@
package io.bisq.api;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import io.bisq.api.model.*;
import io.bisq.api.model.Currency;
import io.bisq.common.app.Version;
@ -12,7 +14,6 @@ import io.bisq.core.btc.AddressEntry;
import io.bisq.core.btc.Restrictions;
import io.bisq.core.btc.wallet.BsqWalletService;
import io.bisq.core.btc.wallet.BtcWalletService;
import io.bisq.core.btc.wallet.WalletService;
import io.bisq.core.offer.*;
import io.bisq.core.payment.*;
import io.bisq.core.provider.fee.FeeService;
@ -29,6 +30,7 @@ import io.bisq.core.util.CoinUtil;
import io.bisq.network.p2p.NodeAddress;
import io.bisq.network.p2p.P2PService;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import lombok.extern.slf4j.Slf4j;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
@ -106,6 +108,10 @@ public class BisqProxy {
return new ArrayList(user.getPaymentAccounts());
}
private PaymentAccount getPaymentAccount(String paymentAccountId) {
return user.getPaymentAccount(paymentAccountId);
}
public AccountList getAccountList() {
AccountList accountList = new AccountList();
accountList.accounts = getPaymentAccountList().stream()
@ -126,20 +132,26 @@ public class BisqProxy {
return true;
}
public Optional<OfferData> getOfferDetail(String offerId) throws Exception {
public Optional<Offer> getOffer(String offerId) throws Exception {
if (Strings.isNullOrEmpty(offerId)) {
throw new Exception("OfferId is null");
}
Optional<Offer> offer = offerBookService.getOffers().stream().filter(offer1 -> offerId.equals(offer1.getId())).findAny();
return offer;
}
public OfferDetail getOfferDetail(String offerId) throws Exception {
Optional<Offer> offer = getOffer(offerId);
if (!offer.isPresent()) {
throw new Exception("OfferId not found");
}
return Optional.of(new OfferData(offer.get()));
return new OfferDetail(offer.get());
}
public List<OfferData> getOfferList() {
//List<OfferData> offer = offerBookService.getOffers().stream().map(offer1 -> new OfferData(offer1)).collect(toList());
List<OfferData> offer = openOfferManager.getObservableList().stream().map(offer1 -> new OfferData(offer1.getOffer())).collect(toList());
public List<OfferDetail> getOfferList() {
//List<OfferDetail> offer = offerBookService.getOffers().stream().map(offer1 -> new OfferDetail(offer1)).collect(toList());
List<OfferDetail> offer = openOfferManager.getObservableList().stream().map(offer1 -> new OfferDetail(offer1.getOffer())).collect(toList());
return offer;
}
@ -150,7 +162,7 @@ public class BisqProxy {
// PaymentAccountUtil.isPaymentAccountValidForOffer
Optional<PaymentAccount> optionalAccount = getPaymentAccountList().stream()
.filter(account1 -> account1.getId().equals(accountId)).findFirst();
if(!optionalAccount.isPresent()) {
if (!optionalAccount.isPresent()) {
// return an error
log.error("Colud not find payment account with id:{}", accountId);
return false;
@ -230,7 +242,7 @@ public class BisqProxy {
hashOfChallenge,
extraDataMap,
Version.TRADE_PROTOCOL_VERSION
);
);
Offer offer = new Offer(offerPayload); // priceFeedService);
@ -238,7 +250,7 @@ public class BisqProxy {
// TODO subtract OfferFee: .subtract(FeePolicy.getCreateOfferFee())
openOfferManager.placeOffer(offer, Coin.valueOf(amount.longValue()),
true, (transaction) -> log.info("Result is " + transaction));
} catch(Throwable e) {
} catch (Throwable e) {
return false;
}
return true;
@ -260,7 +272,7 @@ public class BisqProxy {
private void updateMarketPriceAvailable(String baseCurrencyCode) {
marketPrice = priceFeedService.getMarketPrice(baseCurrencyCode);
marketPriceAvailable = (marketPrice != null );
marketPriceAvailable = (marketPrice != null);
}
@Nullable
@ -291,14 +303,103 @@ public class BisqProxy {
/// STOP TODO refactor out of GUI module ////
public void offerTake() {
//openOfferManager.
///////////////// START TODO REFACTOR OFFER TAKE DEPENDENCIES //////////////////////////
/**
* TakeOfferDataModel.initWithData(Offer) needs to be refactored for fee calculation etc.
*
* @param offerId
* @param paymentAccountId
* @param amount
* @return
* @throws Exception
*/
public boolean offerTake(String offerId, String paymentAccountId, String amount, boolean useSavingsWallet) throws Exception {
// check that the offerId is valid
Optional<Offer> offerOptional = getOffer(offerId);
if(!offerOptional.isPresent()) {
throw new Exception("Unknown offer id");
}
Offer offer = offerOptional.get();
// check the paymentAccountId is valid
PaymentAccount paymentAccount = getPaymentAccount(paymentAccountId);
if(paymentAccount == null) {
throw new Exception("Unknown payment account id");
}
// check the amount is within the range
Coin coinAmount = Coin.valueOf(Long.valueOf(amount));
//if(coinAmount.isLessThan(offer.getMinAmount()) || coinAmount.isGreaterThan(offer.getma)
// check that the price is correct ??
// check taker fee
// check security deposit for BTC buyer
// check security deposit for BTC seller
Coin securityDeposit = offer.getDirection() == OfferPayload.Direction.SELL ?
offer.getBuyerSecurityDeposit() :
offer.getSellerSecurityDeposit();
Coin txFeeFromFeeService = feeService.getTxFee(600);
Coin fundsNeededForTrade = securityDeposit.add(txFeeFromFeeService).add(txFeeFromFeeService);
Platform.runLater(() -> {
tradeManager.onTakeOffer(coinAmount,
txFeeFromFeeService,
getTakerFee(coinAmount),
isCurrencyForTakerFeeBtc(coinAmount),
offer.getPrice().getValue(),
fundsNeededForTrade,
offer,
paymentAccount.getId(),
useSavingsWallet,
(trade) -> log.info("Trade offer taken, offer:{}, trade:{}", offer.getId(), trade.getId()),
errorMessage -> {
log.warn(errorMessage);
}
);
});
return true;
}
boolean isCurrencyForTakerFeeBtc(Coin amount) {
return preferences.getPayFeeInBtc() || !isBsqForFeeAvailable(amount);
}
@Nullable
Coin getTakerFee(Coin amount, boolean isCurrencyForTakerFeeBtc) {
if (amount != null) {
// TODO write unit test for that
Coin feePerBtc = CoinUtil.getFeePerBtc(FeeService.getTakerFeePerBtc(isCurrencyForTakerFeeBtc), amount);
return CoinUtil.maxCoin(feePerBtc, FeeService.getMinTakerFee(isCurrencyForTakerFeeBtc));
} else {
return null;
}
}
@Nullable
public Coin getTakerFee(Coin amount) {
return getTakerFee(amount, isCurrencyForTakerFeeBtc(amount));
}
boolean isBsqForFeeAvailable(Coin amount) {
return BisqEnvironment.isBaseCurrencySupportingBsq() &&
getTakerFee(amount, false) != null &&
bsqWalletService.getAvailableBalance() != null &&
getTakerFee(amount,false) != null &&
!bsqWalletService.getAvailableBalance().subtract(getTakerFee(amount,false)).isNegative();
}
///////////////// END OFFER TAKE DEPENDENCIES //////////////////////////
public TradeList getTradeList() {
TradeList tradeList = new TradeList();
tradeList.setTrades(tradeManager.getTradableList().sorted());
ObservableList<Trade> tradableList = tradeManager.getTradableList();
tradeList.setTrades(tradableList == null || tradableList.size() == 0? Lists.newArrayList():tradableList.sorted());
return tradeList;
}
@ -338,7 +439,7 @@ public class BisqProxy {
public boolean paymentStarted(String tradeId) {
Optional<Trade> tradeOpt = getTrade(tradeId);
if(!tradeOpt.isPresent())
if (!tradeOpt.isPresent())
return false;
Trade trade = tradeOpt.get();
@ -357,7 +458,7 @@ public class BisqProxy {
public boolean paymentReceived(String tradeId) {
Optional<Trade> tradeOpt = getTrade(tradeId);
if(!tradeOpt.isPresent())
if (!tradeOpt.isPresent())
return false;
Trade trade = tradeOpt.get();
TradeProtocol tradeProtocol = trade.getTradeProtocol();
@ -375,7 +476,7 @@ public class BisqProxy {
public boolean moveFundsToBisqWallet(String tradeId) {
Optional<Trade> tradeOpt = getTrade(tradeId);
if(!tradeOpt.isPresent())
if (!tradeOpt.isPresent())
return false;
Trade trade = tradeOpt.get();

View file

@ -26,7 +26,7 @@ import java.util.stream.Collectors;
},
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class OfferData {
public class OfferDetail {
@JsonProperty
String offer_id;
@JsonProperty
@ -53,7 +53,7 @@ public class OfferData {
// offerfeepaymenttxid ???
public OfferData(Offer offer) {
public OfferDetail(Offer offer) {
this.offer_id = offer.getId();
this.direction = offer.getDirection();
this.state = offer.getState();

View file

@ -7,8 +7,6 @@ import io.bisq.api.BisqProxy;
import io.bisq.api.model.*;
import io.bisq.core.offer.OfferPayload;
import io.bisq.core.trade.Trade;
import io.bisq.core.trade.protocol.BuyerAsMakerProtocol;
import io.bisq.core.trade.protocol.TradeProtocol;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotEmpty;
@ -21,6 +19,7 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
@Api(value = "api")
@Path("/api/v1")
@ -104,8 +103,8 @@ public class ApiResourceV1 {
@GET
@Timed
@Path("/offer_detail")
public OfferData offerDetail(@QueryParam("offer_id") String offerId) throws Exception {
return bisqProxy.getOfferDetail(offerId).get();
public OfferDetail offerDetail(@QueryParam("offer_id") String offerId) throws Exception {
return bisqProxy.getOfferDetail(offerId);
}
/**
@ -120,12 +119,12 @@ public class ApiResourceV1 {
@GET
@Timed
@Path("/offer_list")
public List<OfferData> offerList(@DefaultValue("all") @QueryParam("market") String market,
@DefaultValue("all") @QueryParam("status") String status,
@DefaultValue("all") @QueryParam("whose") String whose,
@DefaultValue("0") @QueryParam("start") long start,
@DefaultValue("9223372036854775807") @QueryParam("end") long end,
@DefaultValue("100") @QueryParam("limit") int limit
public List<OfferDetail> offerList(@DefaultValue("all") @QueryParam("market") String market,
@DefaultValue("all") @QueryParam("status") String status,
@DefaultValue("all") @QueryParam("whose") String whose,
@DefaultValue("0") @QueryParam("start") long start,
@DefaultValue("9223372036854775807") @QueryParam("end") long end,
@DefaultValue("100") @QueryParam("limit") int limit
) {
return bisqProxy.getOfferList();
}
@ -163,10 +162,11 @@ public class ApiResourceV1 {
@GET
@Timed
@Path("/offer_take")
public void offerTake(@QueryParam("offer_id") String offerId,
@QueryParam("payment_account_id") String accountId,
@QueryParam("amount") String amount) {
return;
public boolean offerTake(@NotEmpty @QueryParam("offer_id") String offerId,
@NotEmpty @QueryParam("payment_account_id") String paymentAccountId,
@NotEmpty @QueryParam("amount") String amount,
@NotNull @QueryParam("use_savings_wallet") boolean useSavingsWallet) throws Exception {
return bisqProxy.offerTake(offerId, paymentAccountId, amount, useSavingsWallet);
}
@ -193,15 +193,22 @@ public class ApiResourceV1 {
@GET
@Timed
@Path("/trade_list")
public String tradeDetail() throws InvalidProtocolBufferException {
return JsonFormat.printer().print(bisqProxy.getTradeList().getTrade().get(0).toProtoMessage());
}
public String tradeList() throws InvalidProtocolBufferException {
return bisqProxy.getTradeList().trades.stream().map(trade -> trade.toProtoMessage()).map(message -> {
try {
return JsonFormat.printer().print(message);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
return "error";
}).collect(Collectors.joining(", "));
};
@GET
@Timed
@Path("/payment_started")
public boolean paymentStarted(@NotEmpty @QueryParam("trade_id") String tradeId) {
if(!bisqProxy.paymentStarted(tradeId)) {
if (!bisqProxy.paymentStarted(tradeId)) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return true; // TODO return json
@ -211,7 +218,7 @@ public class ApiResourceV1 {
@Timed
@Path("/payment_received")
public boolean paymentReceived(@NotEmpty @QueryParam("trade_id") String tradeId) {
if(!bisqProxy.paymentReceived(tradeId)) {
if (!bisqProxy.paymentReceived(tradeId)) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return true; // TODO return json
@ -224,7 +231,7 @@ public class ApiResourceV1 {
@Timed
@Path("/move_funds_to_bisq_wallet")
public boolean moveFundsToBisqWallet(@NotEmpty @QueryParam("trade_id") String tradeId) {
if(!bisqProxy.moveFundsToBisqWallet(tradeId)) {
if (!bisqProxy.moveFundsToBisqWallet(tradeId)) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return true; // TODO return json