use of bisq.core.trade.Trade in project bisq-api by mrosseel.
the class BisqProxy method paymentStarted.
public CompletableFuture<Void> paymentStarted(String tradeId) {
final CompletableFuture<Void> futureResult = new CompletableFuture<>();
Trade trade;
try {
trade = getTrade(tradeId);
} catch (NotFoundException e) {
return failFuture(futureResult, e);
}
if (!Trade.State.DEPOSIT_CONFIRMED_IN_BLOCK_CHAIN.equals(trade.getState())) {
return failFuture(futureResult, new ValidationException("Trade is not in the correct state to start payment: " + trade.getState()));
}
TradeProtocol tradeProtocol = trade.getTradeProtocol();
ResultHandler resultHandler = () -> futureResult.complete(null);
ErrorMessageHandler errorResultHandler = message -> futureResult.completeExceptionally(new RuntimeException(message));
if (trade instanceof BuyerAsMakerTrade) {
((BuyerAsMakerProtocol) tradeProtocol).onFiatPaymentStarted(resultHandler, errorResultHandler);
} else {
((BuyerAsTakerProtocol) tradeProtocol).onFiatPaymentStarted(resultHandler, errorResultHandler);
}
return futureResult;
}
use of bisq.core.trade.Trade in project bisq-api by mrosseel.
the class BisqProxy method withdrawFunds.
public void withdrawFunds(Set<String> sourceAddresses, Coin amountAsCoin, boolean feeExcluded, String targetAddress) throws AddressEntryException, InsufficientFundsException, AmountTooLowException {
// get all address entries
final List<AddressEntry> sourceAddressEntries = sourceAddresses.stream().filter(address -> null != address).map(address -> btcWalletService.getAddressEntryListAsImmutableList().stream().filter(addressEntry -> address.equals(addressEntry.getAddressString())).findFirst().orElse(null)).filter(item -> null != item).collect(Collectors.toList());
// this filter matches all unauthorized address types
Predicate<AddressEntry> filterNotAllowedAddressEntries = addressEntry -> !(AddressEntry.Context.AVAILABLE.equals(addressEntry.getContext()) || AddressEntry.Context.TRADE_PAYOUT.equals(addressEntry.getContext()));
// check if there are any unauthorized address types
if (sourceAddressEntries.stream().anyMatch(filterNotAllowedAddressEntries)) {
throw new ValidationException("Funds can be withdrawn only from addresses with context AVAILABLE and TRADE_PAYOUT");
}
Coin sendersAmount;
// We do not know sendersAmount if senderPaysFee is true. We repeat fee calculation after first attempt if senderPaysFee is true.
Transaction feeEstimationTransaction;
try {
feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(sourceAddresses, amountAsCoin);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("dust limit")) {
throw new AmountTooLowException(e.getMessage());
}
throw e;
}
if (feeExcluded && feeEstimationTransaction != null) {
sendersAmount = amountAsCoin.add(feeEstimationTransaction.getFee());
feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(sourceAddresses, sendersAmount);
}
checkNotNull(feeEstimationTransaction, "feeEstimationTransaction must not be null");
Coin fee = feeEstimationTransaction.getFee();
sendersAmount = feeExcluded ? amountAsCoin.add(fee) : amountAsCoin;
Coin receiverAmount = feeExcluded ? amountAsCoin : amountAsCoin.subtract(fee);
final Coin totalAvailableAmountOfSelectedItems = sourceAddressEntries.stream().map(address -> btcWalletService.getBalanceForAddress(address.getAddress())).reduce(Coin.ZERO, Coin::add);
if (!sendersAmount.isPositive())
throw new ValidationException("Senders amount must be positive");
if (!new BtcAddressValidator().validate(targetAddress).isValid)
throw new ValidationException("Invalid target address");
if (sourceAddresses.isEmpty())
throw new ValidationException("List of source addresses must not be empty");
if (sendersAmount.compareTo(totalAvailableAmountOfSelectedItems) > 0)
throw new InsufficientFundsException("Not enough funds in selected addresses");
if (receiverAmount.isPositive()) {
try {
// TODO return completable future
btcWalletService.sendFundsForMultipleAddresses(sourceAddresses, targetAddress, amountAsCoin, fee, null, null, new FutureCallback<Transaction>() {
@Override
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
if (transaction != null) {
log.debug("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
} else {
log.error("onWithdraw transaction is null");
}
List<Trade> trades = new ArrayList<>(tradeManager.getTradableList());
trades.stream().filter(Trade::isPayoutPublished).forEach(trade -> btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT).ifPresent(addressEntry -> {
if (btcWalletService.getBalanceForAddress(addressEntry.getAddress()).isZero())
tradeManager.addTradeToClosedTrades(trade);
}));
}
@Override
public void onFailure(@NotNull Throwable t) {
log.error("onWithdraw onFailure");
}
});
} catch (org.bitcoinj.core.InsufficientMoneyException e) {
throw new InsufficientFundsException(e.getMessage());
}
} else {
throw new AmountTooLowException(Res.get("portfolio.pending.step5_buyer.amountTooLow"));
}
}
use of bisq.core.trade.Trade in project bisq-core by bisq-network.
the class ClosedTradableManager method readPersisted.
@Override
public void readPersisted() {
closedTradables = new TradableList<>(tradableListStorage, "ClosedTrades");
closedTradables.forEach(tradable -> {
tradable.getOffer().setPriceFeedService(priceFeedService);
if (tradable instanceof Trade) {
Trade trade = (Trade) tradable;
trade.setTransientFields(tradableListStorage, btcWalletService);
}
});
}
use of bisq.core.trade.Trade in project bisq-core by bisq-network.
the class TradeStatisticsManager method publishTradeStatistics.
public void publishTradeStatistics(List<Trade> trades) {
for (int i = 0; i < trades.size(); i++) {
Trade trade = trades.get(i);
Map<String, String> extraDataMap = null;
if (referralIdService.getOptionalReferralId().isPresent()) {
extraDataMap = new HashMap<>();
extraDataMap.put(OfferPayload.REFERRAL_ID, referralIdService.getOptionalReferralId().get());
}
Offer offer = trade.getOffer();
checkNotNull(offer, "offer must not ne null");
checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not ne null");
TradeStatistics2 tradeStatistics = new TradeStatistics2(offer.getOfferPayload(), trade.getTradePrice(), trade.getTradeAmount(), trade.getDate(), (trade.getDepositTx() != null ? trade.getDepositTx().getHashAsString() : ""), extraDataMap);
addToMap(tradeStatistics, true);
// We only republish trades from last 10 days
if ((new Date().getTime() - trade.getDate().getTime()) < TimeUnit.DAYS.toMillis(10)) {
long delay = 5000;
long minDelay = (i + 1) * delay;
long maxDelay = (i + 2) * delay;
UserThread.runAfterRandomDelay(() -> {
p2PService.addPersistableNetworkPayload(tradeStatistics, true);
}, minDelay, maxDelay, TimeUnit.MILLISECONDS);
}
}
}
use of bisq.core.trade.Trade in project bisq-core by bisq-network.
the class BisqSetup method initDomainServices.
private void initDomainServices() {
log.info("initDomainServices");
clock.start();
PaymentMethod.onAllServicesInitialized();
disputeManager.onAllServicesInitialized();
tradeManager.onAllServicesInitialized();
tradeManager.getTradableList().addListener((ListChangeListener<Trade>) change -> balanceModel.updateBalance());
tradeManager.getAddressEntriesForAvailableBalanceStream().filter(addressEntry -> addressEntry.getOfferId() != null).forEach(addressEntry -> {
log.debug("swapPendingOfferFundingEntries, offerId={}, OFFER_FUNDING", addressEntry.getOfferId());
btcWalletService.swapTradeEntryToAvailableEntry(addressEntry.getOfferId(), AddressEntry.Context.OFFER_FUNDING);
});
btcWalletService.addBalanceListener(new BalanceListener() {
@Override
public void onBalanceChanged(Coin balance, Transaction tx) {
balanceModel.updateBalance();
}
});
if (walletsSetup.downloadPercentageProperty().get() == 1)
checkForLockedUpFunds();
balanceModel.updateBalance();
openOfferManager.getObservableList().addListener((ListChangeListener<OpenOffer>) c -> balanceModel.updateBalance());
openOfferManager.onAllServicesInitialized();
arbitratorManager.onAllServicesInitialized();
alertManager.alertMessageProperty().addListener((observable, oldValue, newValue) -> displayAlertIfPresent(newValue, false));
displayAlertIfPresent(alertManager.alertMessageProperty().get(), false);
privateNotificationManager.privateNotificationProperty().addListener((observable, oldValue, newValue) -> {
if (displayPrivateNotificationHandler != null)
displayPrivateNotificationHandler.accept(newValue);
});
p2PService.onAllServicesInitialized();
feeService.onAllServicesInitialized();
if (DevEnv.isDaoActivated()) {
daoSetup.onAllServicesInitialized(errorMessage -> {
if (daoSetupErrorHandler != null)
daoSetupErrorHandler.accept(errorMessage);
});
}
tradeStatisticsManager.onAllServicesInitialized();
accountAgeWitnessService.onAllServicesInitialized();
priceFeedService.setCurrencyCodeOnInit();
filterManager.onAllServicesInitialized();
filterManager.addListener(filter -> {
if (filter != null && filterWarningHandler != null) {
if (filter.getSeedNodes() != null && !filter.getSeedNodes().isEmpty())
filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.seed")));
if (filter.getPriceRelayNodes() != null && !filter.getPriceRelayNodes().isEmpty())
filterWarningHandler.accept(Res.get("popup.warning.nodeBanned", Res.get("popup.warning.priceRelay")));
}
});
mobileNotificationService.onAllServicesInitialized();
myOfferTakenEvents.onAllServicesInitialized();
tradeEvents.onAllServicesInitialized();
disputeMsgEvents.onAllServicesInitialized();
priceAlert.onAllServicesInitialized();
marketAlerts.onAllServicesInitialized();
allBasicServicesInitialized = true;
}
Aggregations