diff --git a/core/src/main/java/bisq/core/api/model/TradeInfo.java b/core/src/main/java/bisq/core/api/model/TradeInfo.java index cf65cf7799..04887abc8c 100644 --- a/core/src/main/java/bisq/core/api/model/TradeInfo.java +++ b/core/src/main/java/bisq/core/api/model/TradeInfo.java @@ -93,6 +93,8 @@ public class TradeInfo implements Payload { private final boolean isCompleted; private final String contractAsJson; private final ContractInfo contract; + private final boolean hasFailed; + private final String errorMessage; // Optional BSQ swap trade protocol details (post v1). private BsqSwapTradeInfo bsqSwapTradeInfo; private final String closingStatus; @@ -126,6 +128,8 @@ public class TradeInfo implements Payload { this.contract = builder.getContract(); this.bsqSwapTradeInfo = null; this.closingStatus = builder.getClosingStatus(); + this.hasFailed = builder.isHasFailed(); + this.errorMessage = builder.getErrorMessage(); } public static TradeInfo toNewTradeInfo(BsqSwapTrade trade, String role) { @@ -243,6 +247,8 @@ public class TradeInfo implements Payload { .withContractAsJson(trade.getContractAsJson()) .withContract(contractInfo) .withClosingStatus(closingStatus) + .withHasFailed(trade.hasFailed()) + .withErrorMessage(trade.hasErrorMessage() ? trade.getErrorMessage() : "") .build(); } @@ -278,6 +284,8 @@ public class TradeInfo implements Payload { .setIsPaymentReceivedMessageSent(isPaymentReceivedMessageSent) .setIsPayoutPublished(isPayoutPublished) .setIsCompleted(isCompleted) + .setHasFailed(hasFailed) + .setErrorMessage(errorMessage == null ? "" : errorMessage) .setClosingStatus(closingStatus); if (offer.isBsqSwapOffer()) { protoBuilder.setBsqSwapTradeInfo(bsqSwapTradeInfo.toProtoMessage()); @@ -318,6 +326,8 @@ public class TradeInfo implements Payload { .withContractAsJson(proto.getContractAsJson()) .withContract((ContractInfo.fromProto(proto.getContract()))) .withClosingStatus(proto.getClosingStatus()) + .withHasFailed(proto.getHasFailed()) + .withErrorMessage(proto.getErrorMessage()) .build(); if (proto.getOffer().getIsBsqSwapOffer()) @@ -357,6 +367,8 @@ public class TradeInfo implements Payload { ", contract=" + contract + "\n" + ", bsqSwapTradeInfo=" + bsqSwapTradeInfo + "\n" + ", closingStatus=" + closingStatus + "\n" + + ", hasFailed=" + hasFailed + "\n" + + ", errorMessage=" + errorMessage + "\n" + '}'; } } diff --git a/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java b/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java index ea9d2597a6..03109c0276 100644 --- a/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java +++ b/core/src/main/java/bisq/core/api/model/builder/TradeInfoV1Builder.java @@ -56,9 +56,11 @@ public final class TradeInfoV1Builder { private boolean isPaymentReceivedMessageSent; private boolean isPayoutPublished; private boolean isCompleted; + private boolean hasFailed; private String contractAsJson; private ContractInfo contract; private String closingStatus; + private String errorMessage; public TradeInfoV1Builder withOffer(OfferInfo offer) { this.offer = offer; @@ -180,6 +182,16 @@ public final class TradeInfoV1Builder { return this; } + public TradeInfoV1Builder withHasFailed(boolean hasFailed) { + this.hasFailed = hasFailed; + return this; + } + + public TradeInfoV1Builder withErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + return this; + } + public TradeInfoV1Builder withContractAsJson(String contractAsJson) { this.contractAsJson = contractAsJson; return this; diff --git a/core/src/main/java/bisq/core/trade/TradeManager.java b/core/src/main/java/bisq/core/trade/TradeManager.java index b1d7398345..a9224e4943 100644 --- a/core/src/main/java/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/bisq/core/trade/TradeManager.java @@ -108,6 +108,7 @@ import javafx.collections.ObservableList; import org.bouncycastle.crypto.params.KeyParameter; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -911,9 +912,7 @@ public class TradeManager implements PersistedDataHost, DecryptedDirectMessageLi } public List getTrades() { - return getObservableList().stream() - .filter(t -> !t.hasFailed()) - .collect(Collectors.toList()); + return Collections.unmodifiableList(getObservableList()); } private void removeTrade(Trade trade) { diff --git a/proto/src/main/proto/grpc.proto b/proto/src/main/proto/grpc.proto index c4da4756fb..5150aa390c 100644 --- a/proto/src/main/proto/grpc.proto +++ b/proto/src/main/proto/grpc.proto @@ -660,6 +660,10 @@ message TradeInfo { BsqSwapTradeInfo bsq_swap_trade_info = 28; // Needed by open/closed/failed trade list items. string closing_status = 29; + // Whether the trade failed. + bool has_failed = 30; + // Error message applicable when trade is failed. + string error_message = 31; } message ContractInfo {