Merge branch 'dispute-agents-sign-summary' into dispute-agent-branch

This commit is contained in:
chimp1984 2020-09-17 19:07:28 -05:00
commit f46a991101
No known key found for this signature in database
GPG key ID: 9801B4EC591F90E3
17 changed files with 352 additions and 49 deletions

View file

@ -48,6 +48,7 @@ import bisq.network.p2p.SendMailboxMessageListener;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.app.Version; import bisq.common.app.Version;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.PubKeyRing; import bisq.common.crypto.PubKeyRing;
import bisq.common.handlers.FaultHandler; import bisq.common.handlers.FaultHandler;
import bisq.common.handlers.ResultHandler; import bisq.common.handlers.ResultHandler;
@ -63,6 +64,8 @@ import javafx.beans.property.IntegerProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import java.security.KeyPair;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -90,6 +93,8 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
@Getter @Getter
protected final ObservableList<Dispute> disputesWithInvalidDonationAddress = FXCollections.observableArrayList(); protected final ObservableList<Dispute> disputesWithInvalidDonationAddress = FXCollections.observableArrayList();
@Getter
private final KeyPair signatureKeyPair;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -104,7 +109,7 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
OpenOfferManager openOfferManager, OpenOfferManager openOfferManager,
DaoFacade daoFacade, DaoFacade daoFacade,
PubKeyRing pubKeyRing, KeyRing keyRing,
DisputeListService<T> disputeListService, DisputeListService<T> disputeListService,
PriceFeedService priceFeedService) { PriceFeedService priceFeedService) {
super(p2PService, walletsSetup); super(p2PService, walletsSetup);
@ -115,7 +120,8 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
this.closedTradableManager = closedTradableManager; this.closedTradableManager = closedTradableManager;
this.openOfferManager = openOfferManager; this.openOfferManager = openOfferManager;
this.daoFacade = daoFacade; this.daoFacade = daoFacade;
this.pubKeyRing = pubKeyRing; this.pubKeyRing = keyRing.getPubKeyRing();
signatureKeyPair = keyRing.getSignatureKeyPair();
this.disputeListService = disputeListService; this.disputeListService = disputeListService;
this.priceFeedService = priceFeedService; this.priceFeedService = priceFeedService;
} }
@ -267,7 +273,6 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny(); return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny();
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Message handler // Message handler
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -646,7 +651,7 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
} }
// dispute agent send result to trader // dispute agent send result to trader
public void sendDisputeResultMessage(DisputeResult disputeResult, Dispute dispute, String text) { public void sendDisputeResultMessage(DisputeResult disputeResult, Dispute dispute, String summaryText) {
T disputeList = getDisputeList(); T disputeList = getDisputeList();
if (disputeList == null) { if (disputeList == null) {
log.warn("disputes is null"); log.warn("disputes is null");
@ -658,7 +663,7 @@ public abstract class DisputeManager<T extends DisputeList<? extends DisputeList
dispute.getTradeId(), dispute.getTradeId(),
dispute.getTraderPubKeyRing().hashCode(), dispute.getTraderPubKeyRing().hashCode(),
false, false,
text, summaryText,
p2PService.getAddress()); p2PService.getAddress());
disputeResult.setChatMessage(chatMessage); disputeResult.setChatMessage(chatMessage);

View file

@ -54,6 +54,7 @@ import bisq.network.p2p.SendMailboxMessageListener;
import bisq.common.Timer; import bisq.common.Timer;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.app.Version; import bisq.common.app.Version;
import bisq.common.crypto.KeyRing;
import bisq.common.crypto.PubKeyRing; import bisq.common.crypto.PubKeyRing;
import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.AddressFormatException;
@ -90,11 +91,11 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
OpenOfferManager openOfferManager, OpenOfferManager openOfferManager,
DaoFacade daoFacade, DaoFacade daoFacade,
PubKeyRing pubKeyRing, KeyRing keyRing,
ArbitrationDisputeListService arbitrationDisputeListService, ArbitrationDisputeListService arbitrationDisputeListService,
PriceFeedService priceFeedService) { PriceFeedService priceFeedService) {
super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager, super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager,
openOfferManager, daoFacade, pubKeyRing, arbitrationDisputeListService, priceFeedService); openOfferManager, daoFacade, keyRing, arbitrationDisputeListService, priceFeedService);
} }

View file

@ -47,7 +47,7 @@ import bisq.network.p2p.P2PService;
import bisq.common.Timer; import bisq.common.Timer;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.app.Version; import bisq.common.app.Version;
import bisq.common.crypto.PubKeyRing; import bisq.common.crypto.KeyRing;
import bisq.common.handlers.ErrorMessageHandler; import bisq.common.handlers.ErrorMessageHandler;
import bisq.common.handlers.ResultHandler; import bisq.common.handlers.ResultHandler;
@ -82,11 +82,11 @@ public final class MediationManager extends DisputeManager<MediationDisputeList>
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
OpenOfferManager openOfferManager, OpenOfferManager openOfferManager,
DaoFacade daoFacade, DaoFacade daoFacade,
PubKeyRing pubKeyRing, KeyRing keyRing,
MediationDisputeListService mediationDisputeListService, MediationDisputeListService mediationDisputeListService,
PriceFeedService priceFeedService) { PriceFeedService priceFeedService) {
super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager, super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager,
openOfferManager, daoFacade, pubKeyRing, mediationDisputeListService, priceFeedService); openOfferManager, daoFacade, keyRing, mediationDisputeListService, priceFeedService);
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -45,7 +45,7 @@ import bisq.network.p2p.P2PService;
import bisq.common.Timer; import bisq.common.Timer;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.common.app.Version; import bisq.common.app.Version;
import bisq.common.crypto.PubKeyRing; import bisq.common.crypto.KeyRing;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@ -76,11 +76,11 @@ public final class RefundManager extends DisputeManager<RefundDisputeList> {
ClosedTradableManager closedTradableManager, ClosedTradableManager closedTradableManager,
OpenOfferManager openOfferManager, OpenOfferManager openOfferManager,
DaoFacade daoFacade, DaoFacade daoFacade,
PubKeyRing pubKeyRing, KeyRing keyRing,
RefundDisputeListService refundDisputeListService, RefundDisputeListService refundDisputeListService,
PriceFeedService priceFeedService) { PriceFeedService priceFeedService) {
super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager, super(p2PService, tradeWalletService, walletService, walletsSetup, tradeManager, closedTradableManager,
openOfferManager, daoFacade, pubKeyRing, refundDisputeListService, priceFeedService); openOfferManager, daoFacade, keyRing, refundDisputeListService, priceFeedService);
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -1007,11 +1007,24 @@ support.tab.legacyArbitration.support=Legacy Arbitration
support.tab.ArbitratorsSupportTickets={0}'s tickets support.tab.ArbitratorsSupportTickets={0}'s tickets
support.filter=Search disputes support.filter=Search disputes
support.filter.prompt=Enter trade ID, date, onion address or account data support.filter.prompt=Enter trade ID, date, onion address or account data
support.sigCheck.button=Verify result
support.sigCheck.popup.info=In case of a reimbursement request to the DAO you need to paste the summary message of the \
mediation and arbitration process in your reimbursement request on Github. To make this statement verifiable any user can \
check with this tool if the signature of the mediator or arbitrator matches the summary message.
support.sigCheck.popup.header=Verify dispute result signature
support.sigCheck.popup.msg.label=Summary message
support.sigCheck.popup.msg.prompt=Copy & paste summary message from dispute
support.sigCheck.popup.result=Validation result
support.sigCheck.popup.success=Signature is valid
support.sigCheck.popup.failed=Signature verification failed
support.sigCheck.popup.invalidFormat=Message is not of expected format. Copy & paste summary message from dispute.
support.reOpenByTrader.prompt=Are you sure you want to re-open the dispute? support.reOpenByTrader.prompt=Are you sure you want to re-open the dispute?
support.reOpenButton.label=Re-open dispute support.reOpenButton.label=Re-open
support.sendNotificationButton.label=Send private notification support.sendNotificationButton.label=Private notification
support.reportButton.label=Generate report support.reportButton.label=Report
support.fullReportButton.label=Get text dump of all disputes support.fullReportButton.label=All disputes
support.noTickets=There are no open tickets support.noTickets=There are no open tickets
support.sendingMessage=Sending Message... support.sendingMessage=Sending Message...
support.receiverNotOnline=Receiver is not online. Message is saved to their mailbox. support.receiverNotOnline=Receiver is not online. Message is saved to their mailbox.
@ -2446,15 +2459,25 @@ disputeSummaryWindow.reason.TRADE_ALREADY_SETTLED=Trade already settled
disputeSummaryWindow.summaryNotes=Summary notes disputeSummaryWindow.summaryNotes=Summary notes
disputeSummaryWindow.addSummaryNotes=Add summary notes disputeSummaryWindow.addSummaryNotes=Add summary notes
disputeSummaryWindow.close.button=Close ticket disputeSummaryWindow.close.button=Close ticket
disputeSummaryWindow.close.msg=Ticket closed on {0}\n\n\
Summary:\n\ # Do no change any line break or order of tokens as the structure is used for signature verification
Payout amount for BTC buyer: {1}\n\ disputeSummaryWindow.close.msg=Ticket closed on {0}\n\
Payout amount for BTC seller: {2}\n\n\ {1} node address: {2}\n\n\
Reason for dispute: {3}\n\n\ Summary:\n\
Summary notes:\n{4} Trade ID: {3}\n\
disputeSummaryWindow.close.nextStepsForMediation=\n\nNext steps:\n\ Currency: {4}\n\
Trade amount: {5}\n\
Payout amount for BTC buyer: {6}\n\
Payout amount for BTC seller: {7}\n\n\
Reason for dispute: {8}\n\n\
Summary notes:\n{9}\n
# Do no change any line break or order of tokens as the structure is used for signature verification
disputeSummaryWindow.close.msgWithSig={0}{1}{2}{3}
disputeSummaryWindow.close.nextStepsForMediation=\nNext steps:\n\
Open trade and accept or reject suggestion from mediator Open trade and accept or reject suggestion from mediator
disputeSummaryWindow.close.nextStepsForRefundAgentArbitration=\n\nNext steps:\n\ disputeSummaryWindow.close.nextStepsForRefundAgentArbitration=\nNext steps:\n\
No further action is required from you. If the arbitrator decided in your favor, you'll see a "Refund from arbitration" transaction in Funds/Transactions No further action is required from you. If the arbitrator decided in your favor, you'll see a "Refund from arbitration" transaction in Funds/Transactions
disputeSummaryWindow.close.closePeer=You need to close also the trading peers ticket! disputeSummaryWindow.close.closePeer=You need to close also the trading peers ticket!
disputeSummaryWindow.close.txDetails.headline=Publish refund transaction disputeSummaryWindow.close.txDetails.headline=Publish refund transaction

View file

@ -23,6 +23,7 @@ import bisq.desktop.components.BisqTextArea;
import bisq.desktop.components.InputTextField; import bisq.desktop.components.InputTextField;
import bisq.desktop.main.overlays.Overlay; import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.overlays.popups.Popup; import bisq.desktop.main.overlays.popups.Popup;
import bisq.desktop.main.support.dispute.DisputeSummaryVerification;
import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.Layout; import bisq.desktop.util.Layout;
@ -88,8 +89,7 @@ import java.util.Date;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import static bisq.desktop.util.FormBuilder.add2ButtonsWithBox; import static bisq.desktop.util.FormBuilder.add2ButtonsWithBox;
import static bisq.desktop.util.FormBuilder.addConfirmationLabelLabel; import static bisq.desktop.util.FormBuilder.addConfirmationLabelLabel;
@ -97,8 +97,9 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg;
import static bisq.desktop.util.FormBuilder.addTopLabelWithVBox; import static bisq.desktop.util.FormBuilder.addTopLabelWithVBox;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> { public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
private static final Logger log = LoggerFactory.getLogger(DisputeSummaryWindow.class);
private final CoinFormatter formatter; private final CoinFormatter formatter;
private final MediationManager mediationManager; private final MediationManager mediationManager;
@ -109,7 +110,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
private final FeeService feeService; private final FeeService feeService;
private final DaoFacade daoFacade; private final DaoFacade daoFacade;
private Dispute dispute; private Dispute dispute;
private Optional<Runnable> finalizeDisputeHandlerOptional = Optional.<Runnable>empty(); private Optional<Runnable> finalizeDisputeHandlerOptional = Optional.empty();
private ToggleGroup tradeAmountToggleGroup, reasonToggleGroup; private ToggleGroup tradeAmountToggleGroup, reasonToggleGroup;
private DisputeResult disputeResult; private DisputeResult disputeResult;
private RadioButton buyerGetsTradeAmountRadioButton, sellerGetsTradeAmountRadioButton, private RadioButton buyerGetsTradeAmountRadioButton, sellerGetsTradeAmountRadioButton,
@ -227,7 +228,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
else else
disputeResult = dispute.getDisputeResultProperty().get(); disputeResult = dispute.getDisputeResultProperty().get();
peersDisputeOptional = getDisputeManager(dispute).getDisputesAsObservableList().stream() peersDisputeOptional = checkNotNull(getDisputeManager(dispute)).getDisputesAsObservableList().stream()
.filter(d -> dispute.getTradeId().equals(d.getTradeId()) && dispute.getTraderId() != d.getTraderId()) .filter(d -> dispute.getTradeId().equals(d.getTradeId()) && dispute.getTraderId() != d.getTraderId())
.findFirst(); .findFirst();
@ -790,31 +791,52 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
} }
private void doClose(Button closeTicketButton) { private void doClose(Button closeTicketButton) {
DisputeManager<? extends DisputeList<? extends DisputeList>> disputeManager = getDisputeManager(dispute);
if (disputeManager == null) {
return;
}
boolean isRefundAgent = disputeManager instanceof RefundManager;
disputeResult.setLoserPublisher(isLoserPublisherCheckBox.isSelected()); disputeResult.setLoserPublisher(isLoserPublisherCheckBox.isSelected());
disputeResult.setCloseDate(new Date()); disputeResult.setCloseDate(new Date());
dispute.setDisputeResult(disputeResult); dispute.setDisputeResult(disputeResult);
dispute.setIsClosed(true); dispute.setIsClosed(true);
DisputeResult.Reason reason = disputeResult.getReason(); DisputeResult.Reason reason = disputeResult.getReason();
String text = Res.get("disputeSummaryWindow.close.msg",
summaryNotesTextArea.textProperty().unbindBidirectional(disputeResult.summaryNotesProperty());
String role = isRefundAgent ? Res.get("shared.refundAgent") : Res.get("shared.mediator");
String agentNodeAddress = checkNotNull(disputeManager.getAgentNodeAddress(dispute)).getFullAddress();
Contract contract = dispute.getContract();
String currencyCode = contract.getOfferPayload().getCurrencyCode();
String amount = formatter.formatCoinWithCode(contract.getTradeAmount());
String textToSign = Res.get("disputeSummaryWindow.close.msg",
DisplayUtils.formatDateTime(disputeResult.getCloseDate()), DisplayUtils.formatDateTime(disputeResult.getCloseDate()),
role,
agentNodeAddress,
dispute.getShortTradeId(),
currencyCode,
amount,
formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()), formatter.formatCoinWithCode(disputeResult.getBuyerPayoutAmount()),
formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()), formatter.formatCoinWithCode(disputeResult.getSellerPayoutAmount()),
Res.get("disputeSummaryWindow.reason." + reason.name()), Res.get("disputeSummaryWindow.reason." + reason.name()),
disputeResult.summaryNotesProperty().get()); disputeResult.summaryNotesProperty().get()
);
if (reason == DisputeResult.Reason.OPTION_TRADE && if (reason == DisputeResult.Reason.OPTION_TRADE &&
dispute.getChatMessages().size() > 1 && dispute.getChatMessages().size() > 1 &&
dispute.getChatMessages().get(1).isSystemMessage()) { dispute.getChatMessages().get(1).isSystemMessage()) {
text += "\n\n" + dispute.getChatMessages().get(1).getMessage(); textToSign += "\n" + dispute.getChatMessages().get(1).getMessage() + "\n";
} }
if (dispute.getSupportType() == SupportType.MEDIATION) { String summaryText = DisputeSummaryVerification.signAndApply(disputeManager, disputeResult, textToSign);
text += Res.get("disputeSummaryWindow.close.nextStepsForMediation");
} else if (dispute.getSupportType() == SupportType.REFUND) { if (isRefundAgent) {
text += Res.get("disputeSummaryWindow.close.nextStepsForRefundAgentArbitration"); summaryText += Res.get("disputeSummaryWindow.close.nextStepsForRefundAgentArbitration");
} else {
summaryText += Res.get("disputeSummaryWindow.close.nextStepsForMediation");
} }
checkNotNull(getDisputeManager(dispute)).sendDisputeResultMessage(disputeResult, dispute, text); disputeManager.sendDisputeResultMessage(disputeResult, dispute, summaryText);
if (peersDisputeOptional.isPresent() && !peersDisputeOptional.get().isClosed() && !DevEnv.isDevMode()) { if (peersDisputeOptional.isPresent() && !peersDisputeOptional.get().isClosed() && !DevEnv.isDevMode()) {
UserThread.runAfter(() -> new Popup() UserThread.runAfter(() -> new Popup()
@ -824,7 +846,6 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
} }
finalizeDisputeHandlerOptional.ifPresent(Runnable::run); finalizeDisputeHandlerOptional.ifPresent(Runnable::run);
closeTicketButton.disableProperty().unbind(); closeTicketButton.disableProperty().unbind();
hide(); hide();

View file

@ -0,0 +1,96 @@
/*
* 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;
import bisq.desktop.main.overlays.Overlay;
import bisq.desktop.main.support.dispute.DisputeSummaryVerification;
import bisq.core.locale.Res;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import lombok.extern.slf4j.Slf4j;
import static bisq.desktop.util.FormBuilder.addMultilineLabel;
import static bisq.desktop.util.FormBuilder.addTopLabelTextArea;
import static bisq.desktop.util.FormBuilder.addTopLabelTextField;
@Slf4j
public class VerifyDisputeResultSignatureWindow extends Overlay<VerifyDisputeResultSignatureWindow> {
private TextArea textArea;
private TextField resultTextField;
private final MediatorManager mediatorManager;
private final RefundAgentManager refundAgentManager;
public VerifyDisputeResultSignatureWindow(MediatorManager mediatorManager, RefundAgentManager refundAgentManager) {
this.mediatorManager = mediatorManager;
this.refundAgentManager = refundAgentManager;
type = Type.Attention;
}
public void show() {
if (headLine == null)
headLine = Res.get("support.sigCheck.popup.header");
width = 1050;
createGridPane();
addHeadLine();
addContent();
addButtons();
applyStyles();
display();
textArea.textProperty().addListener((observable, oldValue, newValue) -> {
resultTextField.setText(DisputeSummaryVerification.verifySignature(newValue,
mediatorManager,
refundAgentManager));
});
}
@Override
protected void createGridPane() {
gridPane = new GridPane();
gridPane.setHgap(5);
gridPane.setVgap(5);
gridPane.setPadding(new Insets(64, 64, 64, 64));
gridPane.setPrefWidth(width);
ColumnConstraints columnConstraints1 = new ColumnConstraints();
columnConstraints1.setHalignment(HPos.RIGHT);
columnConstraints1.setHgrow(Priority.SOMETIMES);
gridPane.getColumnConstraints().addAll(columnConstraints1);
}
private void addContent() {
addMultilineLabel(gridPane, ++rowIndex, Res.get("support.sigCheck.popup.info"), 0, width);
textArea = addTopLabelTextArea(gridPane, ++rowIndex, Res.get("support.sigCheck.popup.msg.label"),
Res.get("support.sigCheck.popup.msg.prompt")).second;
resultTextField = addTopLabelTextField(gridPane, ++rowIndex, Res.get("support.sigCheck.popup.result")).second;
}
}

View file

@ -0,0 +1,102 @@
/*
* 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.support.dispute;
import bisq.core.locale.Res;
import bisq.core.support.dispute.DisputeList;
import bisq.core.support.dispute.DisputeManager;
import bisq.core.support.dispute.DisputeResult;
import bisq.core.support.dispute.agent.DisputeAgent;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.network.p2p.NodeAddress;
import bisq.common.crypto.CryptoException;
import bisq.common.crypto.Hash;
import bisq.common.crypto.Sig;
import bisq.common.util.Utilities;
import java.security.KeyPair;
import java.security.PublicKey;
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
public class DisputeSummaryVerification {
// Must not change as it is used for splitting the text for verifying the signature of the summary message
private static final String SEPARATOR1 = "\n-----BEGIN SIGNATURE-----\n";
private static final String SEPARATOR2 = "\n-----END SIGNATURE-----\n";
public static String signAndApply(DisputeManager<? extends DisputeList<? extends DisputeList>> disputeManager,
DisputeResult disputeResult,
String textToSign) {
byte[] hash = Hash.getSha256Hash(textToSign);
KeyPair signatureKeyPair = disputeManager.getSignatureKeyPair();
String sigAsHex;
try {
byte[] signature = Sig.sign(signatureKeyPair.getPrivate(), hash);
sigAsHex = Utilities.encodeToHex(signature);
disputeResult.setArbitratorSignature(signature);
} catch (CryptoException e) {
sigAsHex = "Signing failed";
}
return Res.get("disputeSummaryWindow.close.msgWithSig",
textToSign,
SEPARATOR1,
sigAsHex,
SEPARATOR2);
}
public static String verifySignature(String input,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager) {
try {
String[] parts = input.split(SEPARATOR1);
String textToSign = parts[0];
String fullAddress = textToSign.split("\n")[1].split(": ")[1];
NodeAddress nodeAddress = new NodeAddress(fullAddress);
DisputeAgent disputeAgent = mediatorManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
if (disputeAgent == null) {
disputeAgent = refundAgentManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
}
checkNotNull(disputeAgent);
PublicKey pubKey = disputeAgent.getPubKeyRing().getSignaturePubKey();
String sigString = parts[1].split(SEPARATOR2)[0];
byte[] sig = Utilities.decodeFromHex(sigString);
byte[] hash = Hash.getSha256Hash(textToSign);
try {
boolean result = Sig.verify(pubKey, hash, sig);
if (result) {
return Res.get("support.sigCheck.popup.success");
} else {
return Res.get("support.sigCheck.popup.failed");
}
} catch (CryptoException e) {
return Res.get("support.sigCheck.popup.failed");
}
} catch (Throwable e) {
return Res.get("support.sigCheck.popup.invalidFormat");
}
}
}

View file

@ -28,6 +28,7 @@ import bisq.desktop.main.overlays.windows.ContractWindow;
import bisq.desktop.main.overlays.windows.DisputeSummaryWindow; import bisq.desktop.main.overlays.windows.DisputeSummaryWindow;
import bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow; import bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow;
import bisq.desktop.main.overlays.windows.TradeDetailsWindow; import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
import bisq.desktop.main.overlays.windows.VerifyDisputeResultSignatureWindow;
import bisq.desktop.main.shared.ChatView; import bisq.desktop.main.shared.ChatView;
import bisq.desktop.util.DisplayUtils; import bisq.desktop.util.DisplayUtils;
import bisq.desktop.util.GUIUtil; import bisq.desktop.util.GUIUtil;
@ -42,6 +43,8 @@ import bisq.core.support.dispute.DisputeList;
import bisq.core.support.dispute.DisputeManager; import bisq.core.support.dispute.DisputeManager;
import bisq.core.support.dispute.DisputeResult; import bisq.core.support.dispute.DisputeResult;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.support.messages.ChatMessage; import bisq.core.support.messages.ChatMessage;
import bisq.core.trade.Contract; import bisq.core.trade.Contract;
import bisq.core.trade.Trade; import bisq.core.trade.Trade;
@ -121,6 +124,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
private final TradeDetailsWindow tradeDetailsWindow; private final TradeDetailsWindow tradeDetailsWindow;
private final AccountAgeWitnessService accountAgeWitnessService; private final AccountAgeWitnessService accountAgeWitnessService;
private final MediatorManager mediatorManager;
private final RefundAgentManager refundAgentManager;
private final boolean useDevPrivilegeKeys; private final boolean useDevPrivilegeKeys;
protected TableView<Dispute> tableView; protected TableView<Dispute> tableView;
@ -136,7 +141,7 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
protected FilteredList<Dispute> filteredList; protected FilteredList<Dispute> filteredList;
protected InputTextField filterTextField; protected InputTextField filterTextField;
private ChangeListener<String> filterTextFieldListener; private ChangeListener<String> filterTextFieldListener;
protected AutoTooltipButton reOpenButton, sendPrivateNotificationButton, reportButton, fullReportButton; protected AutoTooltipButton sigCheckButton, reOpenButton, sendPrivateNotificationButton, reportButton, fullReportButton;
private Map<String, ListChangeListener<ChatMessage>> disputeChatMessagesListeners = new HashMap<>(); private Map<String, ListChangeListener<ChatMessage>> disputeChatMessagesListeners = new HashMap<>();
@Nullable @Nullable
private ListChangeListener<Dispute> disputesListener; // Only set in mediation cases private ListChangeListener<Dispute> disputesListener; // Only set in mediation cases
@ -157,6 +162,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
ContractWindow contractWindow, ContractWindow contractWindow,
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
boolean useDevPrivilegeKeys) { boolean useDevPrivilegeKeys) {
this.disputeManager = disputeManager; this.disputeManager = disputeManager;
this.keyRing = keyRing; this.keyRing = keyRing;
@ -167,6 +174,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
this.contractWindow = contractWindow; this.contractWindow = contractWindow;
this.tradeDetailsWindow = tradeDetailsWindow; this.tradeDetailsWindow = tradeDetailsWindow;
this.accountAgeWitnessService = accountAgeWitnessService; this.accountAgeWitnessService = accountAgeWitnessService;
this.mediatorManager = mediatorManager;
this.refundAgentManager = refundAgentManager;
this.useDevPrivilegeKeys = useDevPrivilegeKeys; this.useDevPrivilegeKeys = useDevPrivilegeKeys;
} }
@ -222,6 +231,12 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
showFullReport(); showFullReport();
}); });
sigCheckButton = new AutoTooltipButton(Res.get("support.sigCheck.button"));
HBox.setHgrow(sigCheckButton, Priority.NEVER);
sigCheckButton.setOnAction(e -> {
new VerifyDisputeResultSignatureWindow(mediatorManager, refundAgentManager).show();
});
Pane spacer = new Pane(); Pane spacer = new Pane();
HBox.setHgrow(spacer, Priority.ALWAYS); HBox.setHgrow(spacer, Priority.ALWAYS);
@ -234,7 +249,8 @@ public abstract class DisputeView extends ActivatableView<VBox, Void> {
reOpenButton, reOpenButton,
sendPrivateNotificationButton, sendPrivateNotificationButton,
reportButton, reportButton,
fullReportButton); fullReportButton,
sigCheckButton);
VBox.setVgrow(filterBox, Priority.NEVER); VBox.setVgrow(filterBox, Priority.NEVER);
tableView = new TableView<>(); tableView = new TableView<>();

View file

@ -34,6 +34,8 @@ import bisq.core.support.dispute.DisputeList;
import bisq.core.support.dispute.DisputeManager; import bisq.core.support.dispute.DisputeManager;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.agent.MultipleHolderNameDetection; import bisq.core.support.dispute.agent.MultipleHolderNameDetection;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.user.DontShowAgainLookup; import bisq.core.user.DontShowAgainLookup;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -77,6 +79,8 @@ public abstract class DisputeAgentView extends DisputeView implements MultipleHo
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
DaoFacade daoFacade, DaoFacade daoFacade,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
boolean useDevPrivilegeKeys) { boolean useDevPrivilegeKeys) {
super(disputeManager, super(disputeManager,
keyRing, keyRing,
@ -87,6 +91,8 @@ public abstract class DisputeAgentView extends DisputeView implements MultipleHo
contractWindow, contractWindow,
tradeDetailsWindow, tradeDetailsWindow,
accountAgeWitnessService, accountAgeWitnessService,
mediatorManager,
refundAgentManager,
useDevPrivilegeKeys); useDevPrivilegeKeys);
multipleHolderNameDetection = new MultipleHolderNameDetection(disputeManager); multipleHolderNameDetection = new MultipleHolderNameDetection(disputeManager);

View file

@ -31,6 +31,8 @@ import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.arbitration.ArbitrationManager; import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.support.dispute.arbitration.ArbitrationSession; import bisq.core.support.dispute.arbitration.ArbitrationSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -55,6 +57,8 @@ public class ArbitratorView extends DisputeAgentView {
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
DaoFacade daoFacade, DaoFacade daoFacade,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(arbitrationManager, super(arbitrationManager,
keyRing, keyRing,
@ -66,6 +70,8 @@ public class ArbitratorView extends DisputeAgentView {
tradeDetailsWindow, tradeDetailsWindow,
accountAgeWitnessService, accountAgeWitnessService,
daoFacade, daoFacade,
mediatorManager,
refundAgentManager,
useDevPrivilegeKeys); useDevPrivilegeKeys);
} }

View file

@ -31,6 +31,8 @@ import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.MediationManager; import bisq.core.support.dispute.mediation.MediationManager;
import bisq.core.support.dispute.mediation.MediationSession; import bisq.core.support.dispute.mediation.MediationSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -55,6 +57,8 @@ public class MediatorView extends DisputeAgentView {
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
DaoFacade daoFacade, DaoFacade daoFacade,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(mediationManager, super(mediationManager,
keyRing, keyRing,
@ -66,6 +70,8 @@ public class MediatorView extends DisputeAgentView {
tradeDetailsWindow, tradeDetailsWindow,
accountAgeWitnessService, accountAgeWitnessService,
daoFacade, daoFacade,
mediatorManager,
refundAgentManager,
useDevPrivilegeKeys); useDevPrivilegeKeys);
} }

View file

@ -29,8 +29,10 @@ import bisq.core.dao.DaoFacade;
import bisq.core.support.SupportType; import bisq.core.support.SupportType;
import bisq.core.support.dispute.Dispute; import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.RefundManager; import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.support.dispute.refund.RefundSession; import bisq.core.support.dispute.refund.RefundSession;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -55,6 +57,8 @@ public class RefundAgentView extends DisputeAgentView {
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
DaoFacade daoFacade, DaoFacade daoFacade,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(refundManager, super(refundManager,
keyRing, keyRing,
@ -66,6 +70,8 @@ public class RefundAgentView extends DisputeAgentView {
tradeDetailsWindow, tradeDetailsWindow,
accountAgeWitnessService, accountAgeWitnessService,
daoFacade, daoFacade,
mediatorManager,
refundAgentManager,
useDevPrivilegeKeys); useDevPrivilegeKeys);
} }

View file

@ -28,6 +28,8 @@ import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeList; import bisq.core.support.dispute.DisputeList;
import bisq.core.support.dispute.DisputeManager; import bisq.core.support.dispute.DisputeManager;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -43,9 +45,12 @@ public abstract class DisputeClientView extends DisputeView {
ContractWindow contractWindow, ContractWindow contractWindow,
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
boolean useDevPrivilegeKeys) { boolean useDevPrivilegeKeys) {
super(DisputeManager, keyRing, tradeManager, formatter, disputeSummaryWindow, privateNotificationManager, super(DisputeManager, keyRing, tradeManager, formatter, disputeSummaryWindow, privateNotificationManager,
contractWindow, tradeDetailsWindow, accountAgeWitnessService, useDevPrivilegeKeys); contractWindow, tradeDetailsWindow, accountAgeWitnessService,
mediatorManager, refundAgentManager, useDevPrivilegeKeys);
} }
@Override @Override

View file

@ -30,6 +30,8 @@ import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.arbitration.ArbitrationManager; import bisq.core.support.dispute.arbitration.ArbitrationManager;
import bisq.core.support.dispute.arbitration.ArbitrationSession; import bisq.core.support.dispute.arbitration.ArbitrationSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -37,9 +39,8 @@ import bisq.core.util.coin.CoinFormatter;
import bisq.common.config.Config; import bisq.common.config.Config;
import bisq.common.crypto.KeyRing; import bisq.common.crypto.KeyRing;
import javax.inject.Named;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
@FxmlView @FxmlView
public class ArbitrationClientView extends DisputeClientView { public class ArbitrationClientView extends DisputeClientView {
@ -53,10 +54,12 @@ public class ArbitrationClientView extends DisputeClientView {
ContractWindow contractWindow, ContractWindow contractWindow,
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(arbitrationManager, keyRing, tradeManager, formatter, disputeSummaryWindow, super(arbitrationManager, keyRing, tradeManager, formatter, disputeSummaryWindow,
privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService, privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService,
useDevPrivilegeKeys); mediatorManager, refundAgentManager, useDevPrivilegeKeys);
} }
@Override @Override

View file

@ -32,6 +32,8 @@ import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.MediationManager; import bisq.core.support.dispute.mediation.MediationManager;
import bisq.core.support.dispute.mediation.MediationSession; import bisq.core.support.dispute.mediation.MediationSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -54,10 +56,12 @@ public class MediationClientView extends DisputeClientView {
ContractWindow contractWindow, ContractWindow contractWindow,
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(mediationManager, keyRing, tradeManager, formatter, disputeSummaryWindow, super(mediationManager, keyRing, tradeManager, formatter, disputeSummaryWindow,
privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService, privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService,
useDevPrivilegeKeys); mediatorManager, refundAgentManager, useDevPrivilegeKeys);
} }
@Override @Override

View file

@ -28,8 +28,10 @@ import bisq.core.alert.PrivateNotificationManager;
import bisq.core.support.SupportType; import bisq.core.support.SupportType;
import bisq.core.support.dispute.Dispute; import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeSession; import bisq.core.support.dispute.DisputeSession;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.RefundManager; import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.support.dispute.refund.RefundSession; import bisq.core.support.dispute.refund.RefundSession;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.util.FormattingUtils; import bisq.core.util.FormattingUtils;
import bisq.core.util.coin.CoinFormatter; import bisq.core.util.coin.CoinFormatter;
@ -37,9 +39,8 @@ import bisq.core.util.coin.CoinFormatter;
import bisq.common.config.Config; import bisq.common.config.Config;
import bisq.common.crypto.KeyRing; import bisq.common.crypto.KeyRing;
import javax.inject.Named;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
@FxmlView @FxmlView
public class RefundClientView extends DisputeClientView { public class RefundClientView extends DisputeClientView {
@ -53,10 +54,12 @@ public class RefundClientView extends DisputeClientView {
ContractWindow contractWindow, ContractWindow contractWindow,
TradeDetailsWindow tradeDetailsWindow, TradeDetailsWindow tradeDetailsWindow,
AccountAgeWitnessService accountAgeWitnessService, AccountAgeWitnessService accountAgeWitnessService,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager,
@Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) { @Named(Config.USE_DEV_PRIVILEGE_KEYS) boolean useDevPrivilegeKeys) {
super(refundManager, keyRing, tradeManager, formatter, disputeSummaryWindow, super(refundManager, keyRing, tradeManager, formatter, disputeSummaryWindow,
privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService, privateNotificationManager, contractWindow, tradeDetailsWindow, accountAgeWitnessService,
useDevPrivilegeKeys); mediatorManager, refundAgentManager, useDevPrivilegeKeys);
} }
@Override @Override