Skip to content

Commit

Permalink
Merge pull request #6388 from jmacxx/refactor_support_tool
Browse files Browse the repository at this point in the history
Refactor the Support Tool UI
  • Loading branch information
alejandrogarcia83 authored Nov 25, 2022
2 parents 78bd0ce + 5caa401 commit bb428d8
Show file tree
Hide file tree
Showing 10 changed files with 1,125 additions and 825 deletions.
4 changes: 2 additions & 2 deletions desktop/src/main/java/bisq/desktop/app/BisqApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import bisq.desktop.main.overlays.windows.BsqEmptyWalletWindow;
import bisq.desktop.main.overlays.windows.BtcEmptyWalletWindow;
import bisq.desktop.main.overlays.windows.FilterWindow;
import bisq.desktop.main.overlays.windows.ManualPayoutTxWindow;
import bisq.desktop.main.overlays.windows.supporttool.SupportToolWindow;
import bisq.desktop.main.overlays.windows.SendAlertMessageWindow;
import bisq.desktop.main.overlays.windows.ShowWalletDataWindow;
import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
Expand Down Expand Up @@ -354,7 +354,7 @@ private void addSceneKeyEventHandler(Scene scene, Injector injector) {
new Popup().warning(Res.get("popup.warning.walletNotInitialized")).show();
} else if (Utilities.isAltOrCtrlPressed(KeyCode.G, keyEvent)) {
if (injector.getInstance(BtcWalletService.class).isWalletReady())
injector.getInstance(ManualPayoutTxWindow.class).show();
injector.getInstance(SupportToolWindow.class).show();
else
new Popup().warning(Res.get("popup.warning.walletNotInitialized")).show();
} else if (DevEnv.isDevMode()) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.main.overlays.windows.supporttool;

import bisq.desktop.components.AutoTooltipButton;
import bisq.desktop.components.BisqTextArea;
import bisq.desktop.components.InputTextField;
import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.util.GUIUtil;

import bisq.core.btc.exceptions.TransactionVerificationException;
import bisq.core.btc.exceptions.TxBroadcastException;
import bisq.core.btc.exceptions.WalletException;
import bisq.core.btc.setup.WalletsSetup;
import bisq.core.btc.wallet.TradeWalletService;
import bisq.core.btc.wallet.TxBroadcaster;

import bisq.network.p2p.P2PService;

import bisq.common.UserThread;
import bisq.common.util.Tuple2;

import org.bitcoinj.core.AddressFormatException;
import org.bitcoinj.core.SignatureDecodeException;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.VerificationException;

import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;

import javafx.geometry.Pos;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

import static bisq.desktop.util.FormBuilder.addInputTextField;

@Slf4j
public class BuildPane extends CommonPane {

private final TradeWalletService tradeWalletService;
private final P2PService p2PService;
private final WalletsSetup walletsSetup;
private final InputsPane inputsPane;
private final InputTextField buyerSignatureAsHex;
private final InputTextField sellerSignatureAsHex;
private final TextArea finalSignedTxHex;

BuildPane(TradeWalletService tradeWalletService, P2PService p2PService, WalletsSetup walletsSetup, InputsPane inputsPane) {
this.tradeWalletService = tradeWalletService;
this.p2PService = p2PService;
this.walletsSetup = walletsSetup;
this.inputsPane = inputsPane;
int rowIndexA = 0;
buyerSignatureAsHex = addInputTextField(this, ++rowIndexA, "buyerSignatureAsHex");
sellerSignatureAsHex = addInputTextField(this, ++rowIndexA, "sellerSignatureAsHex");
add(new Label(""), 0, ++rowIndexA); // spacer
finalSignedTxHex = new BisqTextArea();
finalSignedTxHex.setEditable(false);
finalSignedTxHex.setWrapText(true);
finalSignedTxHex.setPrefSize(800, 250);
add(finalSignedTxHex, 0, ++rowIndexA);
add(new Label(""), 0, ++rowIndexA); // spacer
Button buttonBuild = new AutoTooltipButton("Build");
Button buttonBroadcast = new AutoTooltipButton("Broadcast");
HBox hBox = new HBox(12, buttonBuild, buttonBroadcast);
hBox.setAlignment(Pos.BASELINE_CENTER);
hBox.setPrefWidth(800);
add(hBox, 0, ++rowIndexA);
buttonBuild.setOnAction(e -> {
finalSignedTxHex.setText(buildFinalTx(false));
});
buttonBroadcast.setOnAction(e -> {
finalSignedTxHex.setText(buildFinalTx(true));
});
}

public void activate() {
finalSignedTxHex.setText("");
super.activate();
}

@Override
public String getName() {
return "Build";
}

private String buildFinalTx(boolean broadcastIt) {
String retVal = "";
inputsPane.calculateTxFee();
// check that all input fields have been entered, including signatures
if (!validateInputFieldsAndSignatures()) {
retVal = "You need to fill in the inputs first";
} else {
try {
// grab data from the inputs pane, build an unsigned tx and write it to the TextArea
Tuple2<String, String> combined = tradeWalletService.emergencyBuildPayoutTxFrom2of2MultiSig(
inputsPane.getDepositTxHex().getText(),
InputsPane.getInputFieldAsCoin(inputsPane.getBuyerPayoutAmount()),
InputsPane.getInputFieldAsCoin(inputsPane.getSellerPayoutAmount()),
InputsPane.getInputFieldAsCoin(inputsPane.getTxFee()),
inputsPane.getBuyerAddressString().getText(),
inputsPane.getSellerAddressString().getText(),
inputsPane.getBuyerPubKeyAsHex().getText(),
inputsPane.getSellerPubKeyAsHex().getText(),
inputsPane.getDepositTxLegacy().isSelected());
String redeemScriptHex = combined.first;
String unsignedTxHex = combined.second;
Tuple2<String, String> txIdAndHex = tradeWalletService.emergencyApplySignatureToPayoutTxFrom2of2MultiSig(
unsignedTxHex,
redeemScriptHex,
buyerSignatureAsHex.getText(),
sellerSignatureAsHex.getText(),
inputsPane.getDepositTxLegacy().isSelected());
retVal = "txId:{" + txIdAndHex.first + "}\r\ntxHex:{" + txIdAndHex.second + "}";

if (broadcastIt) {
TxBroadcaster.Callback callback = new TxBroadcaster.Callback() {
@Override
public void onSuccess(@Nullable Transaction result) {
log.info("onSuccess");
UserThread.execute(() -> {
String txId = result != null ? result.getTxId().toString() : "null";
new Popup().information("Transaction successfully published. Transaction ID: " + txId).show();
});
}
@Override
public void onFailure(TxBroadcastException exception) {
log.error(exception.toString());
UserThread.execute(() -> new Popup().warning(exception.toString()).show());
}
};

if (GUIUtil.isReadyForTxBroadcastOrShowPopup(p2PService, walletsSetup)) {
try {
tradeWalletService.emergencyPublishPayoutTxFrom2of2MultiSig(
txIdAndHex.second,
callback);
} catch (AddressFormatException | WalletException | TransactionVerificationException ee) {
log.error(ee.toString());
ee.printStackTrace();
UserThread.execute(() -> new Popup().warning(ee.toString()).show());
}
}
}
} catch (IllegalArgumentException | SignatureDecodeException | VerificationException ee) {
log.error(ee.toString());
ee.printStackTrace();
retVal = ee.toString();
}
}
return retVal;
}

private boolean validateInputFieldsAndSignatures() {
return (inputsPane.validateInputFields() &&
buyerSignatureAsHex.getText().length() > 0 &&
sellerSignatureAsHex.getText().length() > 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.main.overlays.windows.supporttool;

import javafx.scene.layout.GridPane;

public abstract class CommonPane extends GridPane {

protected static final int HEX_HASH_LENGTH = 32 * 2;
protected static final int HEX_PUBKEY_LENGTH = 33 * 2;

public void activate() {
this.setVisible(true);
}

public void cleanup() {
}

public abstract String getName();

protected static String findPrivForPubOrAddress(String walletInfo, String searchKey) {
// split the walletInfo into lines, strip whitespace
// look for lines beginning " addr:" followed by "DeterministicKey{pub HEX=" .... ", priv HEX="
int lineIndex = 0;
while (lineIndex < walletInfo.length() && lineIndex != -1) {
lineIndex = walletInfo.indexOf(" addr:", lineIndex);
if (lineIndex == -1) {
return null;
}
int toIndex = walletInfo.indexOf("}", lineIndex);
if (toIndex == -1) {
return null;
}
String candidate1 = walletInfo.substring(lineIndex, toIndex);
lineIndex = toIndex;
// do we have the search key?
if (candidate1.indexOf(searchKey, 0) > -1) {
int startOfPriv = candidate1.indexOf("priv HEX=", 0);
if (startOfPriv > -1) {
return candidate1.substring(startOfPriv + 9, startOfPriv + 9 + HEX_HASH_LENGTH);
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.main.overlays.windows.supporttool;

import bisq.desktop.components.BisqTextArea;

import javafx.scene.control.TextArea;

public class ExportPane extends CommonPane {

private final InputsPane inputsPane;
private final TextArea exportHex;

ExportPane(InputsPane inputsPane) {
this.inputsPane = inputsPane;
exportHex = new BisqTextArea();
exportHex.setEditable(false);
exportHex.setWrapText(true);
exportHex.setPrefSize(800, 250);
add(exportHex, 0, 1);
}

@Override
public void activate() {
// export pane is populated from the inputs pane fields
exportHex.setText(inputsPane.generateExportText());
super.activate();
}

@Override
public String getName() {
return "Export";
}
}
Loading

0 comments on commit bb428d8

Please sign in to comment.