Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add memo field at step4 #4908

Merged
merged 2 commits into from
Dec 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions core/src/main/java/bisq/core/api/CoreApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

/**
* Provides high level interface to functionality of core Bisq features.
* E.g. useful for different APIs to access data of different domains of Bisq.
Expand Down Expand Up @@ -208,8 +210,8 @@ public void keepFunds(String tradeId) {
coreTradesService.keepFunds(tradeId);
}

public void withdrawFunds(String tradeId, String address) {
coreTradesService.withdrawFunds(tradeId, address);
public void withdrawFunds(String tradeId, String address, @Nullable String memo) {
coreTradesService.withdrawFunds(tradeId, address, memo);
}

public Trade getTrade(String tradeId) {
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/bisq/core/api/CoreTradesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

import static bisq.core.btc.model.AddressEntry.Context.TRADE_PAYOUT;
import static java.lang.String.format;

Expand Down Expand Up @@ -154,7 +156,7 @@ void keepFunds(String tradeId) {
tradeManager.onTradeCompleted(trade);
}

void withdrawFunds(String tradeId, String toAddress) {
void withdrawFunds(String tradeId, String toAddress, @Nullable String memo) {
// An encrypted wallet must be unlocked for this operation.
verifyTradeIsNotClosed(tradeId);
var trade = getOpenTrade(tradeId).orElseThrow(() ->
Expand Down Expand Up @@ -184,6 +186,7 @@ void withdrawFunds(String tradeId, String toAddress) {
fee,
coreWalletsService.getKey(),
trade,
memo,
() -> {
},
(errorMessage, throwable) -> {
Expand Down
36 changes: 21 additions & 15 deletions core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ private Transaction completePreparedProposalTx(Transaction feeTx, byte[] opRetur
sendRequest.signInputs = false;

sendRequest.fee = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);

sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;
Expand All @@ -274,8 +274,8 @@ private Transaction completePreparedProposalTx(Transaction feeTx, byte[] opRetur
numSegwitInputs = numInputs.second;
txVsizeWithUnsignedInputs = resultTx.getVsize();
long estimatedFeeAsLong = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;

// calculated fee must be inside of a tolerance range with tx fee
isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000;
Expand Down Expand Up @@ -374,8 +374,8 @@ private Transaction addInputsForMinerFee(Transaction preparedTx,
sendRequest.signInputs = false;

sendRequest.fee = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;

Expand All @@ -393,8 +393,8 @@ private Transaction addInputsForMinerFee(Transaction preparedTx,
numSegwitInputs = numInputs.second;
txVsizeWithUnsignedInputs = resultTx.getVsize();
final long estimatedFeeAsLong = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;
// calculated fee must be inside of a tolerance range with tx fee
isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000;
}
Expand Down Expand Up @@ -532,8 +532,8 @@ public Transaction completePreparedBsqTx(Transaction preparedBsqTx,
sendRequest.signInputs = false;

sendRequest.fee = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4);
sendRequest.feePerKb = Coin.ZERO;
sendRequest.ensureMinRequiredFee = false;

Expand All @@ -558,8 +558,8 @@ public Transaction completePreparedBsqTx(Transaction preparedBsqTx,
numSegwitInputs = numInputs.second;
txVsizeWithUnsignedInputs = resultTx.getVsize();
final long estimatedFeeAsLong = txFeePerVbyte.multiply(txVsizeWithUnsignedInputs +
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;
sigSizePerInput * numLegacyInputs +
sigSizePerInput * numSegwitInputs / 4).value;
// calculated fee must be inside of a tolerance range with tx fee
isFeeOutsideTolerance = Math.abs(resultTx.getFee().value - estimatedFeeAsLong) > 1000;
}
Expand All @@ -583,7 +583,7 @@ private Tuple2<Integer, Integer> getNumInputs(Transaction tx) {
for (TransactionInput input : tx.getInputs()) {
TransactionOutput connectedOutput = input.getConnectedOutput();
if (connectedOutput == null || ScriptPattern.isP2PKH(connectedOutput.getScriptPubKey()) ||
ScriptPattern.isP2PK(connectedOutput.getScriptPubKey())) {
ScriptPattern.isP2PK(connectedOutput.getScriptPubKey())) {
// If connectedOutput is null, we don't know here the input type. To avoid underpaying fees,
// we treat it as a legacy input which will result in a higher fee estimation.
numLegacyInputs++;
Expand Down Expand Up @@ -1100,12 +1100,15 @@ public String sendFunds(String fromAddress,
Coin fee,
@Nullable KeyParameter aesKey,
@SuppressWarnings("SameParameterValue") AddressEntry.Context context,
@Nullable String memo,
FutureCallback<Transaction> callback) throws AddressFormatException,
AddressEntryException, InsufficientMoneyException {
SendRequest sendRequest = getSendRequest(fromAddress, toAddress, receiverAmount, fee, aesKey, context);
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
Futures.addCallback(sendResult.broadcastComplete, callback, MoreExecutors.directExecutor());

if (memo != null) {
sendResult.tx.setMemo(memo);
}
printTx("sendFunds", sendResult.tx);
return sendResult.tx.getTxId().toString();
}
Expand All @@ -1116,13 +1119,16 @@ public Transaction sendFundsForMultipleAddresses(Set<String> fromAddresses,
Coin fee,
@Nullable String changeAddress,
@Nullable KeyParameter aesKey,
@Nullable String memo,
FutureCallback<Transaction> callback) throws AddressFormatException,
AddressEntryException, InsufficientMoneyException {

SendRequest request = getSendRequestForMultipleAddresses(fromAddresses, toAddress, receiverAmount, fee, changeAddress, aesKey);
Wallet.SendResult sendResult = wallet.sendCoins(request);
Futures.addCallback(sendResult.broadcastComplete, callback, MoreExecutors.directExecutor());

if (memo != null) {
sendResult.tx.setMemo(memo);
}
printTx("sendFunds", sendResult.tx);
return sendResult.tx;
}
Expand Down
13 changes: 10 additions & 3 deletions core/src/main/java/bisq/core/trade/TradeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,14 @@ private OfferAvailabilityModel getOfferAvailabilityModel(Offer offer) {
// Complete trade
///////////////////////////////////////////////////////////////////////////////////////////

public void onWithdrawRequest(String toAddress, Coin amount, Coin fee, KeyParameter aesKey,
Trade trade, ResultHandler resultHandler, FaultHandler faultHandler) {
public void onWithdrawRequest(String toAddress,
Coin amount,
Coin fee,
KeyParameter aesKey,
Trade trade,
@Nullable String memo,
ResultHandler resultHandler,
FaultHandler faultHandler) {
String fromAddress = btcWalletService.getOrCreateAddressEntry(trade.getId(),
AddressEntry.Context.TRADE_PAYOUT).getAddressString();
FutureCallback<Transaction> callback = new FutureCallback<>() {
Expand All @@ -487,7 +493,8 @@ public void onFailure(@NotNull Throwable t) {
}
};
try {
btcWalletService.sendFunds(fromAddress, toAddress, amount, fee, aesKey, AddressEntry.Context.TRADE_PAYOUT, callback);
btcWalletService.sendFunds(fromAddress, toAddress, amount, fee, aesKey,
AddressEntry.Context.TRADE_PAYOUT, memo, callback);
} catch (AddressFormatException | InsufficientMoneyException | AddressEntryException e) {
e.printStackTrace();
log.error(e.getMessage());
Expand Down
3 changes: 2 additions & 1 deletion daemon/src/main/java/bisq/daemon/grpc/GrpcTradesService.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ public void keepFunds(KeepFundsRequest req,
public void withdrawFunds(WithdrawFundsRequest req,
StreamObserver<WithdrawFundsReply> responseObserver) {
try {
coreApi.withdrawFunds(req.getTradeId(), req.getAddress());
//TODO @ghubstan Feel free to add a memo param for withdrawal requests (was just added in UI)
coreApi.withdrawFunds(req.getTradeId(), req.getAddress(), null);
var reply = WithdrawFundsReply.newBuilder().build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,14 +494,19 @@ private void doWithdraw(Coin amount, Coin fee, FutureCallback<Transaction> callb

private void sendFunds(Coin amount, Coin fee, KeyParameter aesKey, FutureCallback<Transaction> callback) {
try {
String memo = withdrawMemoTextField.getText();
if (memo.isEmpty()) {
memo = null;
}
Transaction transaction = btcWalletService.sendFundsForMultipleAddresses(fromAddresses,
withdrawToTextField.getText(),
amount,
fee,
null,
aesKey,
memo,
callback);
transaction.setMemo(withdrawMemoTextField.getText());

reset();
updateList();
} catch (AddressFormatException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ public void onWithdrawRequest(String toAddress,
Coin amount,
Coin fee,
KeyParameter aesKey,
@Nullable String memo,
ResultHandler resultHandler,
FaultHandler faultHandler) {
checkNotNull(getTrade(), "trade must not be null");
Expand All @@ -220,6 +221,7 @@ public void onWithdrawRequest(String toAddress,
fee,
aesKey,
getTrade(),
memo,
() -> {
resultHandler.handleResult();
selectBestItem();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
public class BuyerStep4View extends TradeStepView {
// private final ChangeListener<Boolean> focusedPropertyListener;

private InputTextField withdrawAddressTextField;
private InputTextField withdrawAddressTextField, withdrawMemoTextField;
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
private TitledGroupBg withdrawTitledGroupBg;

Expand Down Expand Up @@ -131,10 +131,17 @@ protected void addContent() {
withdrawTitledGroupBg = addTitledGroupBg(gridPane, ++gridRow, 1, Res.get("portfolio.pending.step5_buyer.withdrawBTC"), Layout.COMPACT_GROUP_DISTANCE);
withdrawTitledGroupBg.getStyleClass().add("last");
addCompactTopLabelTextField(gridPane, gridRow, Res.get("portfolio.pending.step5_buyer.amount"), model.getPayoutAmount(), Layout.FIRST_ROW_AND_GROUP_DISTANCE);

withdrawAddressTextField = addInputTextField(gridPane, ++gridRow, Res.get("portfolio.pending.step5_buyer.withdrawToAddress"));
withdrawAddressTextField.setManaged(false);
withdrawAddressTextField.setVisible(false);

withdrawMemoTextField = addInputTextField(gridPane, ++gridRow,
Res.get("funds.withdrawal.memoLabel", Res.getBaseCurrencyCode()));
withdrawMemoTextField.setPromptText(Res.get("funds.withdrawal.memo"));
withdrawMemoTextField.setManaged(false);
withdrawMemoTextField.setVisible(false);

HBox hBox = new HBox();
hBox.setSpacing(10);
useSavingsWalletButton = new AutoTooltipButton(Res.get("portfolio.pending.step5_buyer.moveToBisqWallet"));
Expand Down Expand Up @@ -170,7 +177,9 @@ protected void addContent() {
private void onWithdrawal() {
withdrawAddressTextField.setManaged(true);
withdrawAddressTextField.setVisible(true);
GridPane.setRowSpan(withdrawTitledGroupBg, 2);
withdrawMemoTextField.setManaged(true);
withdrawMemoTextField.setVisible(true);
GridPane.setRowSpan(withdrawTitledGroupBg, 3);
withdrawToExternalWalletButton.setDefaultButton(true);
useSavingsWalletButton.setDefaultButton(false);
withdrawToExternalWalletButton.getStyleClass().add("action-button");
Expand Down Expand Up @@ -271,10 +280,15 @@ private void doWithdrawRequest(String toAddress,
FaultHandler faultHandler) {
useSavingsWalletButton.setDisable(true);
withdrawToExternalWalletButton.setDisable(true);
String memo = withdrawMemoTextField.getText();
if (memo.isEmpty()) {
memo = null;
}
model.dataModel.onWithdrawRequest(toAddress,
amount,
fee,
aesKey,
memo,
resultHandler,
faultHandler);
}
Expand Down