use of bisq.core.offer.Offer in project bisq-core by bisq-network.
the class CreateMakerFeeTx method run.
@Override
protected void run() {
Offer offer = model.getOffer();
try {
runInterceptHook();
String id = offer.getId();
BtcWalletService walletService = model.getWalletService();
NodeAddress selectedArbitratorNodeAddress = ArbitratorSelectionRule.select(model.getUser().getAcceptedArbitratorAddresses(), model.getOffer());
log.debug("selectedArbitratorAddress " + selectedArbitratorNodeAddress);
Arbitrator selectedArbitrator = model.getUser().getAcceptedArbitratorByAddress(selectedArbitratorNodeAddress);
checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateOfferFeeTx");
Address fundingAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING).getAddress();
Address reservedForTradeAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
final TradeWalletService tradeWalletService = model.getTradeWalletService();
if (offer.isCurrencyForMakerFeeBtc()) {
tradeFeeTx = tradeWalletService.createBtcTradingFeeTx(fundingAddress, reservedForTradeAddress, changeAddress, model.getReservedFundsForOffer(), model.isUseSavingsWallet(), offer.getMakerFee(), offer.getTxFee(), selectedArbitrator.getBtcAddress(), new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
// we delay one render frame to be sure we don't get called before the method call has
// returned (tradeFeeTx would be null in that case)
UserThread.execute(() -> {
if (!completed) {
offer.setOfferFeePaymentTxId(transaction.getHashAsString());
model.setTransaction(transaction);
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
complete();
} else {
log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
}
});
}
@Override
public void onFailure(@NotNull Throwable t) {
if (!completed) {
failed(t);
} else {
log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
}
}
});
} else {
final BsqWalletService bsqWalletService = model.getBsqWalletService();
Transaction preparedBurnFeeTx = model.getBsqWalletService().getPreparedBurnFeeTx(offer.getMakerFee());
Transaction txWithBsqFee = tradeWalletService.completeBsqTradingFeeTx(preparedBurnFeeTx, fundingAddress, reservedForTradeAddress, changeAddress, model.getReservedFundsForOffer(), model.isUseSavingsWallet(), offer.getTxFee());
Transaction signedTx = model.getBsqWalletService().signTx(txWithBsqFee);
WalletService.checkAllScriptSignaturesForTx(signedTx);
bsqWalletService.commitTx(signedTx);
// We need to create another instance, otherwise the tx would trigger an invalid state exception
// if it gets committed 2 times
tradeWalletService.commitTx(tradeWalletService.getClonedTransaction(signedTx));
bsqWalletService.broadcastTx(signedTx, new FutureCallback<Transaction>() {
@Override
public void onSuccess(@Nullable Transaction transaction) {
if (transaction != null) {
offer.setOfferFeePaymentTxId(transaction.getHashAsString());
model.setTransaction(transaction);
log.debug("onSuccess, offerId={}, OFFER_FUNDING", id);
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
log.debug("Successfully sent tx with id " + transaction.getHashAsString());
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);
complete();
}
}
@Override
public void onFailure(@NotNull Throwable t) {
log.error(t.toString());
t.printStackTrace();
offer.setErrorMessage("An error occurred.\n" + "Error message:\n" + t.getMessage());
failed(t);
}
});
}
} catch (Throwable t) {
offer.setErrorMessage("An error occurred.\n" + "Error message:\n" + t.getMessage());
failed(t);
}
}
use of bisq.core.offer.Offer in project bisq-core by bisq-network.
the class ValidateOffer method run.
@Override
protected void run() {
Offer offer = model.getOffer();
try {
runInterceptHook();
// Coins
checkCoinNotNullOrZero(offer.getAmount(), "Amount");
checkCoinNotNullOrZero(offer.getMinAmount(), "MinAmount");
checkCoinNotNullOrZero(offer.getMakerFee(), "MakerFee");
checkCoinNotNullOrZero(offer.getBuyerSecurityDeposit(), "buyerSecurityDeposit");
checkCoinNotNullOrZero(offer.getSellerSecurityDeposit(), "sellerSecurityDeposit");
checkCoinNotNullOrZero(offer.getTxFee(), "txFee");
checkCoinNotNullOrZero(offer.getMaxTradeLimit(), "MaxTradeLimit");
// We remove those checks to be more flexible with future changes.
/*checkArgument(offer.getMakerFee().value >= FeeService.getMinMakerFee(offer.isCurrencyForMakerFeeBtc()).value,
"createOfferFee must not be less than FeeService.MIN_CREATE_OFFER_FEE_IN_BTC. " +
"MakerFee=" + offer.getMakerFee().toFriendlyString());*/
/*checkArgument(offer.getBuyerSecurityDeposit().value >= ProposalConsensus.getMinBuyerSecurityDeposit().value,
"buyerSecurityDeposit must not be less than ProposalConsensus.MIN_BUYER_SECURITY_DEPOSIT. " +
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
checkArgument(offer.getBuyerSecurityDeposit().value <= ProposalConsensus.getMaxBuyerSecurityDeposit().value,
"buyerSecurityDeposit must not be larger than ProposalConsensus.MAX_BUYER_SECURITY_DEPOSIT. " +
"buyerSecurityDeposit=" + offer.getBuyerSecurityDeposit().toFriendlyString());
checkArgument(offer.getSellerSecurityDeposit().value == ProposalConsensus.getSellerSecurityDeposit().value,
"sellerSecurityDeposit must be equal to ProposalConsensus.SELLER_SECURITY_DEPOSIT. " +
"sellerSecurityDeposit=" + offer.getSellerSecurityDeposit().toFriendlyString());*/
/*checkArgument(offer.getMinAmount().compareTo(ProposalConsensus.getMinTradeAmount()) >= 0,
"MinAmount is less then " + ProposalConsensus.getMinTradeAmount().toFriendlyString());*/
checkArgument(offer.getAmount().compareTo(offer.getPaymentMethod().getMaxTradeLimitAsCoin(offer.getCurrencyCode())) <= 0, "Amount is larger then " + offer.getPaymentMethod().getMaxTradeLimitAsCoin(offer.getCurrencyCode()).toFriendlyString());
checkArgument(offer.getAmount().compareTo(offer.getMinAmount()) >= 0, "MinAmount is larger then Amount");
checkNotNull(offer.getPrice(), "Price is null");
checkArgument(offer.getPrice().isPositive(), "Price must be positive. price=" + offer.getPrice().toFriendlyString());
checkArgument(offer.getDate().getTime() > 0, "Date must not be 0. date=" + offer.getDate().toString());
checkNotNull(offer.getArbitratorNodeAddresses(), "Arbitrator is null");
checkNotNull(offer.getMediatorNodeAddresses(), "Mediator is null");
checkNotNull(offer.getCurrencyCode(), "Currency is null");
checkNotNull(offer.getDirection(), "Direction is null");
checkNotNull(offer.getId(), "Id is null");
checkNotNull(offer.getPubKeyRing(), "pubKeyRing is null");
checkNotNull(offer.getMinAmount(), "MinAmount is null");
checkNotNull(offer.getPrice(), "Price is null");
checkNotNull(offer.getTxFee(), "txFee is null");
checkNotNull(offer.getMakerFee(), "MakerFee is null");
checkNotNull(offer.getVersionNr(), "VersionNr is null");
checkArgument(offer.getMaxTradePeriod() > 0, "maxTradePeriod must be positive. maxTradePeriod=" + offer.getMaxTradePeriod());
// TODO check upper and lower bounds for fiat
// TODO check rest of new parameters
complete();
} catch (Exception e) {
offer.setErrorMessage("An error occurred.\n" + "Error message:\n" + e.getMessage());
failed(e);
}
}
use of bisq.core.offer.Offer in project bisq-core by bisq-network.
the class AccountAgeWitnessService method verifyPeersTradeLimit.
private boolean verifyPeersTradeLimit(Trade trade, AccountAgeWitness peersWitness, Date peersCurrentDate, ErrorMessageHandler errorMessageHandler) {
Offer offer = trade.getOffer();
Coin tradeAmount = checkNotNull(trade.getTradeAmount());
final String currencyCode = offer.getCurrencyCode();
final Coin defaultMaxTradeLimit = PaymentMethod.getPaymentMethodById(offer.getOfferPayload().getPaymentMethodId()).getMaxTradeLimitAsCoin(currencyCode);
long peersCurrentTradeLimit = getTradeLimit(defaultMaxTradeLimit, currencyCode, Optional.of(peersWitness), peersCurrentDate);
// Makers current trade limit cannot be smaller than that in the offer
boolean result = tradeAmount.value <= peersCurrentTradeLimit;
if (!result) {
String msg = "The peers trade limit is less than the traded amount.\n" + "tradeAmount=" + tradeAmount.toFriendlyString() + "\nPeers trade limit=" + Coin.valueOf(peersCurrentTradeLimit).toFriendlyString();
log.warn(msg);
errorMessageHandler.handleErrorMessage(msg);
}
return result;
}
use of bisq.core.offer.Offer in project bisq-core by bisq-network.
the class SellerAsMakerCreatesAndSignsDepositTx method run.
@Override
protected void run() {
try {
runInterceptHook();
checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
BtcWalletService walletService = processModel.getBtcWalletService();
String id = processModel.getOffer().getId();
TradingPeer tradingPeer = processModel.getTradingPeer();
final Offer offer = trade.getOffer();
// params
final boolean makerIsBuyer = false;
final byte[] contractHash = Hash.getSha256Hash(trade.getContractAsJson());
trade.setContractHash(contractHash);
log.debug("\n\n------------------------------------------------------------\n" + "Contract as json\n" + trade.getContractAsJson() + "\n------------------------------------------------------------\n");
final Coin makerInputAmount = offer.getSellerSecurityDeposit().add(trade.getTradeAmount());
Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
AddressEntry makerMultiSigAddressEntry = addressEntryOptional.get();
makerMultiSigAddressEntry.setCoinLockedInMultiSig(makerInputAmount);
walletService.saveAddressEntryList();
final Coin msOutputAmount = makerInputAmount.add(trade.getTxFee()).add(offer.getBuyerSecurityDeposit());
final List<RawTransactionInput> takerRawTransactionInputs = tradingPeer.getRawTransactionInputs();
final long takerChangeOutputValue = tradingPeer.getChangeOutputValue();
final String takerChangeAddressString = tradingPeer.getChangeOutputAddress();
final Address makerAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
final Address makerChangeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
final byte[] buyerPubKey = tradingPeer.getMultiSigPubKey();
final byte[] sellerPubKey = processModel.getMyMultiSigPubKey();
checkArgument(Arrays.equals(sellerPubKey, makerMultiSigAddressEntry.getPubKey()), "sellerPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
final byte[] arbitratorBtcPubKey = trade.getArbitratorBtcPubKey();
PreparedDepositTxAndMakerInputs result = processModel.getTradeWalletService().makerCreatesAndSignsDepositTx(makerIsBuyer, contractHash, makerInputAmount, msOutputAmount, takerRawTransactionInputs, takerChangeOutputValue, takerChangeAddressString, makerAddress, makerChangeAddress, buyerPubKey, sellerPubKey, arbitratorBtcPubKey);
processModel.setPreparedDepositTx(result.depositTransaction);
processModel.setRawTransactionInputs(result.rawMakerInputs);
complete();
} catch (Throwable t) {
failed(t);
}
}
use of bisq.core.offer.Offer in project bisq-core by bisq-network.
the class TradeManager method handleInitialTakeOfferRequest.
private void handleInitialTakeOfferRequest(TradeMessage message, NodeAddress peerNodeAddress) {
log.trace("handleNewMessage: message = " + message.getClass().getSimpleName() + " from " + peerNodeAddress);
try {
Validator.nonEmptyStringOf(message.getTradeId());
} catch (Throwable t) {
log.warn("Invalid requestDepositTxInputsMessage " + message.toString());
return;
}
Optional<OpenOffer> openOfferOptional = openOfferManager.findOpenOffer(message.getTradeId());
if (openOfferOptional.isPresent() && openOfferOptional.get().getState() == OpenOffer.State.AVAILABLE) {
Offer offer = openOfferOptional.get().getOffer();
openOfferManager.reserveOpenOffer(openOfferOptional.get());
checkArgument(message instanceof PayDepositRequest, "message must be PayDepositRequest");
PayDepositRequest payDepositRequest = (PayDepositRequest) message;
Trade trade;
if (offer.isBuyOffer())
trade = new BuyerAsMakerTrade(offer, Coin.valueOf(payDepositRequest.getTxFee()), Coin.valueOf(payDepositRequest.getTakerFee()), payDepositRequest.isCurrencyForTakerFeeBtc(), tradableListStorage, btcWalletService);
else
trade = new SellerAsMakerTrade(offer, Coin.valueOf(payDepositRequest.getTxFee()), Coin.valueOf(payDepositRequest.getTakerFee()), payDepositRequest.isCurrencyForTakerFeeBtc(), tradableListStorage, btcWalletService);
initTrade(trade, trade.getProcessModel().isUseSavingsWallet(), trade.getProcessModel().getFundsNeededForTradeAsLong());
tradableList.add(trade);
((MakerTrade) trade).handleTakeOfferRequest(message, peerNodeAddress, errorMessage -> {
if (takeOfferRequestErrorMessageHandler != null)
takeOfferRequestErrorMessageHandler.handleErrorMessage(errorMessage);
});
} else {
// TODO respond
// (RequestDepositTxInputsMessage)message.
// messageService.sendEncryptedMessage(peerAddress,messageWithPubKey.getMessage().);
log.debug("We received a take offer request but don't have that offer anymore.");
}
}
Aggregations