mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 23:18:17 +01:00
Merge pull request #4908 from chimp1984/add-memo-field-at-step4
Add memo field at step4
This commit is contained in:
commit
6431d639ae
8 changed files with 65 additions and 25 deletions
|
@ -45,6 +45,8 @@ import java.util.function.Consumer;
|
|||
|
||||
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.
|
||||
|
@ -208,8 +210,8 @@ public class CoreApi {
|
|||
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) {
|
||||
|
|
|
@ -41,6 +41,8 @@ import java.util.function.Consumer;
|
|||
|
||||
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;
|
||||
|
||||
|
@ -154,7 +156,7 @@ class CoreTradesService {
|
|||
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(() ->
|
||||
|
@ -184,6 +186,7 @@ class CoreTradesService {
|
|||
fee,
|
||||
coreWalletsService.getKey(),
|
||||
trade,
|
||||
memo,
|
||||
() -> {
|
||||
},
|
||||
(errorMessage, throwable) -> {
|
||||
|
|
|
@ -254,8 +254,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
|
@ -274,8 +274,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
|
@ -374,8 +374,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
|
||||
|
@ -393,8 +393,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
}
|
||||
|
@ -532,8 +532,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
|
||||
|
@ -558,8 +558,8 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ public class BtcWalletService extends WalletService {
|
|||
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++;
|
||||
|
@ -1100,12 +1100,15 @@ public class BtcWalletService extends WalletService {
|
|||
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();
|
||||
}
|
||||
|
@ -1116,13 +1119,16 @@ public class BtcWalletService extends WalletService {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -462,8 +462,14 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||
// 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<>() {
|
||||
|
@ -487,7 +493,8 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi
|
|||
}
|
||||
};
|
||||
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());
|
||||
|
|
|
@ -144,7 +144,8 @@ class GrpcTradesService extends TradesGrpc.TradesImplBase {
|
|||
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();
|
||||
|
|
|
@ -494,14 +494,19 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -209,6 +209,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
Coin amount,
|
||||
Coin fee,
|
||||
KeyParameter aesKey,
|
||||
@Nullable String memo,
|
||||
ResultHandler resultHandler,
|
||||
FaultHandler faultHandler) {
|
||||
checkNotNull(getTrade(), "trade must not be null");
|
||||
|
@ -220,6 +221,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
fee,
|
||||
aesKey,
|
||||
getTrade(),
|
||||
memo,
|
||||
() -> {
|
||||
resultHandler.handleResult();
|
||||
selectBestItem();
|
||||
|
|
|
@ -74,7 +74,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
|
|||
public class BuyerStep4View extends TradeStepView {
|
||||
// private final ChangeListener<Boolean> focusedPropertyListener;
|
||||
|
||||
private InputTextField withdrawAddressTextField;
|
||||
private InputTextField withdrawAddressTextField, withdrawMemoTextField;
|
||||
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
|
||||
private TitledGroupBg withdrawTitledGroupBg;
|
||||
|
||||
|
@ -131,10 +131,17 @@ public class BuyerStep4View extends TradeStepView {
|
|||
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"));
|
||||
|
@ -170,7 +177,9 @@ public class BuyerStep4View extends TradeStepView {
|
|||
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");
|
||||
|
@ -271,10 +280,15 @@ public class BuyerStep4View extends TradeStepView {
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue